更多內容,請訪問 https://my.oschina.net/u/5751...html
GenericObjectPool 是 Apache Commons Pool 提供的對象池,使用的時候須要調用 borrowObject 獲取一個對象,使用完之後須要調用 returnObject 歸還對象,或者調用 invalidateObject 將這個對象標記爲不可再用。java
實際應用中因爲程序實現的問題,可能形成在一些極端的狀況下出現 borrowObject/invalidateObject 沒有被調用致使的泄漏問題。對象泄漏會致使對象池中的對象數量一直上升,達到設置的上限之後再調用 borrowObject 就會永遠等待或者拋出 java.util.NoSuchElementException: Timeout waiting for idle object
異常。apache
對於這種問題,一方面是從應用實現上進行排查,另外一方面能夠經過 GenericObjectPool 自帶的機制進行清理。.net
GenericObjectPool判斷一個對象是否泄漏是根據對象最後一次使用或者最後一次borrow的時間進行判斷的,若是超出了預設的值就會被認爲是一個泄漏的對象被清理掉(PooledObjectFactory.destroyObject在這一過程當中會被調用)。拋棄時間能夠經過 AbandonedConfig.setRemoveAbandonedTimeout 進行設置,時間單位是秒。code
設置了拋棄時間之後還須要打開泄漏清理纔會生效。泄漏判斷的開啓能夠經過兩種方式:htm
從對象池中獲取對象的時候進行清理
若是當前對象池中少於2個idle狀態的對象或者 active數量>最大對象數-3 的時候,在borrow對象的時候啓動泄漏清理。經過 AbandonedConfig.setRemoveAbandonedOnBorrow 爲 true 進行開啓。對象
啓動定時任務進行清理
AbandonedConfig.setRemoveAbandonedOnMaintenance 設置爲 true 之後,在維護任務運行的時候會進行泄漏對象的清理,能夠經過 GenericObjectPool.setTimeBetweenEvictionRunsMillis 設置維護任務執行的時間間隔。blog
GenericObjectPool<PoolObj> pool = new GenericObjectPool<PoolObj>(new MyPooledObjectFactory(),config); AbandonedConfig abandonedConfig = new AbandonedConfig(); abandonedConfig.setRemoveAbandonedOnMaintenance(true); //在Maintenance的時候檢查是否有泄漏 abandonedConfig.setRemoveAbandonedOnBorrow(true); //borrow 的時候檢查泄漏 abandonedConfig.setRemoveAbandonedTimeout(10); //若是一個對象borrow以後10秒尚未返還給pool,認爲是泄漏的對象 pool.setAbandonedConfig(abandonedConfig); pool.setTimeBetweenEvictionRunsMillis(5000); //5秒運行一次維護任務