[英]Singleton over collections of objects in Java and garbage collector
[英]Java Collections and Garbage Collector
關於Java Web應用程序性能的一個小問題。
假設我有一個包含十個Rubrique
對象的List<Rubrique>
listRubriques
。
Rubrique
包含一個產品List<product>
( List<product>
listProducts
)和一個客戶List<Client>
( List<Client>
listClients
)。
如果我這樣做,內存中究竟會發生什么:
listRubriques.clear(); listRubriques = null;
我的觀點是,因為listRubriques
是空的,所以此列表之前引用的所有對象(包括listProducts
和listClients
)很快就會被垃圾收集。 但是因為Java中的Collection有點棘手,因為我的應用程序存在相當大的性能問題,我問的問題是:)
編輯:我們現在假設我的Client對象包含List<Client>
。 因此,我的對象之間有一個循環引用。 如果我的listRubrique
設置為null
會發生什么? 這一次,我的觀點是我的客戶端對象將變得“無法訪問”並可能造成內存泄漏?
Java的實際Sun實現不時復制所有引用/生存對象。 然后,復制的空間可以再次用於內存分配。
那說你的例子會損害實際的表現。 listRubriques.clear()
是不必要的(除了你在其他地方有一個對它的引用),因為listRubrique引用的所有內容都是垃圾,不再引用listRubriques。 如果變量listRubriques之后超出范圍,則listRubriques = null
也可能不需要(可能因為它是局部變量,並且方法在這里結束)。
不僅不需要清除調用,因為clear訪問后來不再使用的對象的內存,訪問對象並且現代處理器將其放入緩存中。 因此,死對象明確地轉到處理器緩存 - 一些可能更有用的數據將被覆蓋用於該操作。
本文是獲取有關Java垃圾收集器的更多信息的一個很好的參考。
編輯 :對問題中的編輯作出反應:垃圾收集器(至少由Sun使用的實現)從一些根引用開始,並復制它可以從此引用到達的所有對象以及復制對象引用的對象。 所以你的循環引用對象是垃圾,因為沒有'外部'引用指向它們,內存將在垃圾收集中回收。
如果你有:
listRubriques = null;
並且沒有其他對象持有對listRubriques
或其包含對象的引用,它有資格進行垃圾回收。 但是無法保證JVM何時會實際運行垃圾收集並釋放內存。 你可以打電話:
System.gc();
向JVM推薦您認為此時運行垃圾收集是一個好主意。 但即便如此,也無法保證。
也有
listRubriques.clear();
在將listRubriques
設置為null
之前不需要。
編輯 :為了回答有關循環引用的問題,JVM足夠聰明,可以確定整個對象圖與任何正在運行的代碼斷開連接,並且JVM將正確地確定它們都符合垃圾回收的條件。 即使在引用計數的舊時代,這一直都是如此。 現代JVM更快,更高效。 但它們不是垃圾收集任何更多的對象而不是舊的JVM。
“很快”是一個相當模糊的規范,但垃圾收集器可能沒有你想象的那么快。 實際收集對象時,很大程度上取決於GC配置和服務器負載,但可能需要一些時間,如果您的VM有足夠的可用堆和其他事情要做,那么“很快”就不會收集這些對象。 。
VM規范保證GC運行的唯一情況是,在某些時候否則會拋出OutOfMemoryError。 在拋出OutOfMemoryError之前,VM有義務嘗試至少收集這么多符合條件的對象實例,相關的內存分配請求可以成功(但是仍然不能保證收集所有符合條件的實例)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.