11、關(guān)于對(duì)象池的思考

對(duì)象池作為全局資源,高并發(fā)環(huán)境中多個(gè)線程可能同時(shí)需要獲取對(duì)象池的對(duì)象,因此多個(gè)線程在爭(zhēng)搶對(duì)象時(shí)因?yàn)殒i競(jìng)爭(zhēng)而阻塞,因此使用對(duì)象池有線程同步的開銷,而不使用對(duì)象池則有創(chuàng)建和銷毀對(duì)象的開銷。對(duì)于對(duì)象池本身的設(shè)計(jì)來(lái)說,需要盡量做到無(wú)鎖化,比如Jetty就使用了ConcurrentLinkedDeque。如果你的內(nèi)存足夠大,可以考慮線程本地對(duì)象池,這樣每個(gè)線程都有自己的對(duì)象池,線程之間互不干擾。

為了防止對(duì)象池的無(wú)限膨脹,必須要對(duì)池的大小做限制。對(duì)象池太小發(fā)揮不了作用,對(duì)象池太大的話可能有空閑對(duì)象,這些空閑對(duì)象會(huì)一直占用內(nèi)存,造成內(nèi)存浪費(fèi)。這里你需要根據(jù)實(shí)際情況做一個(gè)平衡,因此對(duì)象池本身除了應(yīng)該有自動(dòng)擴(kuò)容的功能,還需要考慮自動(dòng)縮容。

所有的池化技術(shù),包括緩存,都會(huì)面臨內(nèi)存泄露的問題,原因是對(duì)象池或者緩存的本質(zhì)是一個(gè)Java集合類,比如List和Stack,這個(gè)集合類持有緩存對(duì)象的引用,只要集合類不被GC,緩存對(duì)象也不會(huì)被GC。維持大量的對(duì)象也比較占用內(nèi)存空間,所以必要時(shí)我們需要主動(dòng)清理這些對(duì)象。以Java的線程ThreadPoolExecutor
為例,它提供了allowCoreThreadTimeOut和setKeepAliveTime兩種方法,可以在超時(shí)后銷毀線程,我們?cè)趯?shí)際項(xiàng)目中也可以參考這個(gè)策略。

另外在使用對(duì)象池時(shí),我這里還有一些小貼士供你參考:

  • 對(duì)象在用完后,需要調(diào)用對(duì)象池的方法將對(duì)象歸還給對(duì)象池。
  • 對(duì)象池中的對(duì)象在再次使用時(shí)需要重置,否則會(huì)產(chǎn)生臟對(duì)象,臟對(duì)象可能持有上次使用的引用,導(dǎo)致內(nèi)存泄漏等問題,并且如果臟對(duì)象下一次使用時(shí)沒有被清理,程序在運(yùn)行過程中會(huì)發(fā)生意想不到的問題。
  • 對(duì)象一旦歸還給對(duì)象池,使用者就不能對(duì)它做任何操作了。
  • 向?qū)ο蟪卣?qǐng)求對(duì)象時(shí)有可能出現(xiàn)的阻塞、異?;蛘叻祷豱ull值,這些都需要我們做一些額外的處理,來(lái)確保程序的正常運(yùn)行。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容