我們知道了在Java中確實(shí)會(huì )存在內存泄漏,那么就讓我們看一看幾種典型的泄漏,并找出他們發(fā)生的原因和解決方法。
全局集合
在大型應用程序中存在各種各樣的全局數據倉庫是很普遍的,比如一個(gè)JNDI-tree或者一個(gè)session table。在這些情況下,必須注意管理儲存庫的大小。必須有某種機制從儲存庫中移除不再需要的數據。
通常有很多不同的解決形式,其中最常用的是一種周期運行的清除作業(yè)。這個(gè)作業(yè)會(huì )驗證倉庫中的數據然后清除一切不需要的數據。
另一種管理儲存庫的方法是使用反向鏈接(referrer)計數。然后集合負責統計集合中每個(gè)入口的反向鏈接的數目。這要求反向鏈接告訴集合何時(shí)會(huì )退出入口。當反向鏈接數目為零時(shí),該元素就可以從集合中移除了。
緩存
緩存一種用來(lái)快速查找已經(jīng)執行過(guò)的操作結果的數據結構。因此,如果一個(gè)操作執行需要比較多的資源并會(huì )多次被使用,通常做法是把常用的輸入數據的操作結果進(jìn)行緩存,以便在下次調用該操作時(shí)使用緩存的數據。緩存通常都是以動(dòng)態(tài)方式實(shí)現的,如果緩存設置不正確而大量使用緩存的話(huà)則會(huì )出現內存溢出的后果,因此需要將所使用的內存容量與檢索數據的速度加以平衡。
常用的解決途徑是使用java.lang.ref.SoftReference類(lèi)堅持將對象放入緩存。這個(gè)方法可以保證當虛擬機用完內存或者需要更多堆的時(shí)候,可以釋放這些對象的引用。
類(lèi)裝載器
Java類(lèi)裝載器的使用為內存泄漏提供了許多可乘之機。一般來(lái)說(shuō)類(lèi)裝載器都具有復雜結構,因為類(lèi)裝載器不僅僅是只與"常規"對象引用有關(guān),同時(shí)也和對象內部的引用有關(guān)。比如數據變量,方法和各種類(lèi)。這意味著(zhù)只要存在對數據變量,方法,各種類(lèi)和對象的類(lèi)裝載器,那么類(lèi)裝載器將駐留在JVM中。既然類(lèi)裝載器可以同很多的類(lèi)關(guān)聯(lián),同時(shí)也可以和靜態(tài)數據變量關(guān)聯(lián),那么相當多的內存就可能發(fā)生泄漏。
【編輯推薦】
聯(lián)系客服