2013-05-27 56 views
2

這是我懷疑的想法,並且認爲這樣做是爲了好事。
假設我有加載爲我的應用程序的一部分,下面的類:無法識別內存的內存問題

class HeavyClass { 
    static final ArrayList list = new ArrayList(100); 
} 

是否靜態成員的生命週期對準自己的應用程序,不管發生了什麼HeavyClass的實例。
如果靜態本身與不被垃圾回收的類加載器內存(permgen)保持一致,那麼確保這樣一個對象僅僅需要消耗(並清除成員)的編程習慣是什麼;假設我們必須有一個靜態要在所有實例中共享)

回答

1

靜態成員的生命週期是否與應用程序保持一致,而不管HeavyClass的實例發生了什麼。

差不多,是的。見BevnQ的答案。

如果靜態贊同的類加載器存儲器(PermGen的),這是不被垃圾收集...

雖然用於一個類中的靜態幀是(通常)在分配的PermGen:

  1. permgen內存>>是< <垃圾收集,和
  2. 從靜態框架(例如arraylist)的對象引用沒有分配permgen。

但是,這些事實實際上都不會改變任何東西......除非您的應用程序成功處理加載相關類的類加載器。

什麼編程成語,以確保這樣的對象僅消耗(和清理會員)需要的基礎上,假設我們有一個靜態跨所有實例共享)

問題是知道何時不再需要成員。如果可以重新生成成員,則可以使用弱引用來實現緩存。這是一個常用的解決方案,並且工作得很好,儘管您可能想要對緩存大小進行限制。 (無界高速緩存可能會消耗大量內存,這些內存可以更好地用於其他事情,但不會得到OOME,但最終會更頻繁地運行GC。)

否則,您需要實現某種引用計數機制,並希望共享數據結構中的所有「客戶」都遵守規則......始終。這不是一個好的解決方案。

我的建議是找出如何避免使用靜態或(更一般地)永久「可達到root」的大型共享數據結構。

6

靜態變量存在於類對象的整個生命週期中。也就是說,它們是在類加載時創建的,並且通常只在ClassLoader被丟棄時纔會死掉。

如果該列表將被附着到的HeavyClass一個實例,你不應該讓它static, 在finalize方法調用list.clear()會給你unpredictable results

參考java language spec

8.3.1.1。靜態字段

如果一個字段被聲明爲靜態,那麼無論該類最終可能創建了多少個實例(可能爲零),該字段都只有一個化身。一個靜態字段,有時稱爲類變量,在類被初始化時被體現(§12.4)。