<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
物件池,顧名思義就是一定數量的已經建立好的物件(Object)的集合。當需要建立物件時,先在池子中獲取,如果池子中沒有符合條件的物件,再進行建立新物件,同樣,當物件需要銷燬時,不做真正的銷燬,而是將其setActive(false),並存入池子中。這樣就避免了大量物件的建立。
減少頻繁建立和銷燬物件帶來的成本,實現物件的快取和複用,建立物件的成本比較大,並且建立比較頻繁。比如執行緒的建立代價比較大,於是就有了常用的執行緒 池。物件池(模式)是一種建立型設計模式,它持有一個初始化好的物件的集合,將物件提供給呼叫者。
一般而言對於 建立物件的成本比較大,並且建立比較頻繁。比如執行緒的建立代價比較大,於是就有了常用的執行緒池。
提升了t獲取物件的響應速度,比如單個執行緒和資源連線的建立成本都比較大。
運用物件池化技術可以顯著地提升效能,尤其是當物件的初始化過程代價較大或者頻率較高時。
一定程度上減少了GC的壓力。對於實時性要求較高的程式有很大的幫助
比如說 http 連結的物件池,Redis物件池等等都使用了物件池
1.髒物件的問題
所謂的髒物件就是指的是當物件被放回物件池後,還保留著剛剛被使用者端呼叫時生成的資料。
髒物件可能帶來兩個問題:
1).髒物件持有上次使用的參照,導致記憶體漏失等問題。
2). 髒物件如果下一次使用時沒有做清理,可能影響程式的處理資料。
2.生命週期的問題
處於物件池中的物件生命週期要比普通的物件要長久。維持大量的物件也是比較佔用記憶體空間的。
一般來說,物件池有下面幾個特徵:
(1)物件池中有一定數量已經建立好的物件
(2)物件池向用戶提供獲取物件的介面,當用戶需要新的物件時,便可通過呼叫此介面獲取新的物件。如果物件池中有事先建立好的物件時,就直接返回給用 戶;如果沒有了,物件池還可以建立新的物件加入其中,然後返回給使用者
(3)物件池向用戶提供歸還物件的介面,當用戶不再使用某物件時,便可通過此介面把該物件歸還給物件池
通常情況下,我們需要控制物件池的大小如果物件池沒有限制,可能導致物件池持有過多的閒置物件,增加記憶體的佔用。如果物件池閒置過小,沒有可用的物件時,會造成之前物件池無可用的物件時,再次請求出現的問題。
物件池的大小選取應該結合具體的使用場景,結合資料(觸發池中無可用物件的頻率)分析來確定。現在Java的物件分配操作不比c語言的malloc呼叫慢, 對於輕中量級的物件, 分配/釋放物件的開銷可以忽略不計,並行環境中, 多個執行緒可能(同時)需要獲取池中物件, 進而需要在堆資料結構上進行同步或者因為鎖競爭而產生阻塞, 這種開銷要比建立銷燬物件的開銷高數百倍;由於池中物件的數量有限, 勢必成為一個可伸縮性瓶頸;很難正確的設定物件池的大小, 如果太小則起不到作用, 如果過大, 則佔用記憶體資源高。
空間換時間的折中,本質上,物件池屬於空間換時間的折中。它通過快取初始化好的物件來提升呼叫者請求物件的響應速度。除此之外,折中(tradeoff)是軟體開發中的一個重要的概念,會貫穿整個軟體開發過程中。
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
import com.scl.online.service.model.SxInferContext; import org.apache.commons.pool2.PooledObject; import org.apache.commons.pool2.PooledObjectFactory; import org.apache.commons.pool2.impl.DefaultPooledObject; /** * 實現PooledObjectFactory * * @author : cuilinsu * @since : 2021/4/14 17:56 */ public class InferContextPooledObjectFactory implements PooledObjectFactory<SxInferContext> { @Override public PooledObject<SxInferContext> makeObject() { SxInferContext inferContext = new SxInferContext(); return new DefaultPooledObject<>(inferContext); } @Override public void destroyObject(PooledObject<SxInferContext> pooledObject) { } @Override public boolean validateObject(PooledObject<SxInferContext> pooledObject) { return true; } @Override public void activateObject(PooledObject<SxInferContext> pooledObject) { pooledObject.getObject().initObject(); } @Override public void passivateObject(PooledObject<SxInferContext> pooledObject) { // 當ObjectPool範例返還池中的時候呼叫 pooledObject.getObject().initObject(); } }
說明:
1.SxInferContext:為物件池裡頭的物件,物件借還都會呼叫到PooledObjectFactory裡頭的方法
2.PooledObjectFactory負責管理PooledObject,如:借出物件,返回物件,校驗物件,有多少啟用物件,有多少空閒物件。
方法 | 描述 |
---|---|
makeObject | 用於生成一個新的ObjectPool範例 |
activateObject | 每一個鈍化(passivated)的ObjectPool範例從池中借出(borrowed)前呼叫 |
validateObject | 可能用於從池中借出物件時,對處於啟用(activated)狀態的ObjectPool範例進行測試確保它是有效的。也有可能在ObjectPool範例返還池中進行鈍化前呼叫進行測試是否有效。它只對處於啟用狀態的範例呼叫 |
passivateObject | 當ObjectPool範例返還池中的時候呼叫 |
destroyObject | 當ObjectPool範例從池中被清理出去丟棄的時候呼叫(是否根據validateObject的測試結果由具體的實現在而定) |
public GenericObjectPool<SxInferContext> contextPools; @PostConstruct public void init() { if (sxInferConfig.isObjectPoolUsable()) { InferContextPooledObjectFactory factory = new InferContextPooledObjectFactory(); //設定物件池的相關引數 GenericObjectPoolConfig poolConfig = initConfig(); //新建一個物件池,傳入物件工廠和設定 contextPools = new GenericObjectPool<>(factory, poolConfig); } } /** * 池子初始化 * * @param */ public GenericObjectPoolConfig initConfig() { GenericObjectPoolConfig cfg = new GenericObjectPoolConfig(); cfg.setJmxNamePrefix("objectPool"); // 物件總數 cfg.setMaxTotal(sxInferConfig.getPoolMaxTotal()); // 最大空閒物件數 cfg.setMaxIdle(sxInferConfig.getPoolMaxIdle()); // 最小空閒物件數 cfg.setMinIdle(sxInferConfig.getPoolMinIdle()); // 借物件阻塞最大等待時間 // 獲取資源的等待時間。blockWhenExhausted 為 true 時有效。-1 代表無時間限制,一直阻塞直到有可用的資源 cfg.setMaxWaitMillis(sxInferConfig.getPoolMaxWait()); // 最小驅逐空閒時間 cfg.setMinEvictableIdleTimeMillis(sxInferConfig.getPoolMinEvictableIdleTimeMillis()); // 每次驅逐數量 資源回收執行緒執行一次回收操作,回收資源的數量。預設 3 cfg.setNumTestsPerEvictionRun(sxInferConfig.getPoolNumTestsPerEvictionRun()); // 回收資源執行緒的執行週期,預設 -1 表示不啟用回收資源執行緒 cfg.setTimeBetweenEvictionRunsMillis(sxInferConfig.getPoolTimeBetweenEvictionRunsMillis()); // 資源耗盡時,是否阻塞等待獲取資源,預設 true cfg.setBlockWhenExhausted(sxInferConfig.isPoolBlockWhenExhausted()); return cfg; }
contextPools.borrowObject();
contextPools.returnObject();
等等 ....
說明:cfg.setJmxNamePrefix(“objectPool”); 假如專案中有用到redis執行緒池,則需要設定一下JmxNamePrefix。redis執行緒池使用的是“pool”,假如有重複的,早呼叫執行緒池是時,就預設會呼叫到Redis執行緒池的PooledObjectFactory(假如redis執行緒池使用預設的話),導致設定的執行緒池不生效。
GenericObjectPool 方法解釋:
方法 | 描述 |
---|---|
borrowObject | 從池中借出一個物件。要麼呼叫PooledObjectFactory.makeObject方法建立,要麼對一個空閒物件使用PooledObjectFactory.activeObject進行啟用,然後使用PooledObjectFactory.validateObject方法進行驗證後再返回 |
returnObject | 將一個物件返還給池。根據約定:物件必須 是使用borrowObject方法從池中借出的 |
invalidateObject | 廢棄一個物件。根據約定:物件必須 是使用borrowObject方法從池中借出的。通常在物件發生了異常或其他問題時使用此方法廢棄它 |
addObject | 使用工廠建立一個物件,鈍化並且將它放入空閒物件池 |
getNumberIdle | 返回池中空閒的物件數量。有可能是池中可供借出物件的近似值。如果這個資訊無效,返回一個負數 |
getNumActive | 返回從借出的物件數量。如果這個資訊不可用,返回一個負數 |
clear | 清除池中的所有空閒物件,釋放其關聯的資源(可選)。清除空閒物件必須使用PooledObjectFactory.destroyObject方法 |
close | 關閉池並釋放關聯的資源 |
到此這篇關於詳解Java中物件池的介紹與使用的文章就介紹到這了,更多相關Java物件池內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45