2011-07-04 30 views
19

靜態變量分配給整個程序執行期間,所以堆棧 和堆都不方便。那它在哪裏?應該有一些地方加載?什麼是靜態變量的實際內存位置?

+2

另請參閱:http://www.daniweb.com/software-development/java/threads/34695 – mnicky

+0

@mnicky謝謝!這是有幫助的。 – Reuben

+0

[其中是一個靜態方法和存儲在java中的靜態變量。在堆或堆棧內存中](http://stackoverflow.com/questions/8387989/where-is-a-static-method-and-a-static-variable-stored-in-java-in-heap-or- in-sta) –

回答

15

當一個類被加載時,靜態字段被初始化,而當該類的類加載器被卸載時,被放棄。它們可以被清理,甚至可以在另一個類加載器中複製。

對於那些使用OSGi的應用程序來說,靜態變量在應用程序的整個生命週期中都不會生效,可以多次重新加載。

實現方式可能與JVM有關,但Sun/Oracle JVM會創建一個「對象」來存放類的靜態字段。這個對象可以通過Unsafe類訪問,它也可以用來檢查這個「objects」字段。

1

http://www.daniweb.com/software-development/java/threads/34695

的靜態變量的存儲器是在節目的開始分配 ,在 常規存儲器,而不是堆棧 (存儲器用於 程序預留​​特異性)。這樣做的好處是 它使你的變量或 程序完全不變,而你 不會意外地改變這個值。 這樣做的缺點是, 內存不會被釋放,直到 程序終止。我從來沒有聽說過任何靜態值取 任何更多的內存,如果他們是 定期申報,但他們的內存 使用是恆定的通過。

+1

-1:「完全不變」?你在想「終結」嗎?並且內存不會被釋放直到結束;這不是一個缺點,這就是'靜態'的全部意義! –

+1

@OliCharlesworth,他在談論「靜態final」變量。與不必這樣做相比,被迫更長時間地使用更多內存是不利的。 – Pacerier

7

靜態變量分配給整個程序執行期間,所以堆棧和堆都不方便。

實際上,靜態幀(即保存靜態變量的幀)是從堆中分配的。

它們不一定在程序執行期間存在。例如,如果父類加載器,所有類和所有實例都變得無法訪問,則可以垃圾收集動態加載的類的靜態幀。

24

我們必須在我們的記憶3段:

  1. 堆棧段—包括局部變量和參考變量(即持有對象的地址在堆中變量)。

  2. 堆段—包含運行時所有創建的對象,只包含對象及其對象屬性(實例變量)。

  3. 代碼段—加載時實際編譯的Java字節碼所在的段。 靜態成員(變量或方法)被稱爲類成員,這意味着它們駐留在代碼段中的類(字節碼)所在的位置。

+6

這個答案已經投了這麼多,但與http://stackoverflow.com/questions/3849634/static-allocation-in-java-heap-stack-and-permanent-generation/3849819#3849819 – ravindrab

+3

Sourav矛盾,你能請給你的消息來源? –

+1

也許Sourav指的是C++? – flow2k

1

缺貨的該JVM使用五個存儲區,靜態字段在等級地區(PremGen的一部分)當類由應用程序的類加載器準備並裝載階段期間加載分配的內存。 如果該字段是原始字段,則該值存儲在類區域中,如果該字段屬於對象類型(使用新操作符),則將其存儲在堆中,但引用會被分配給類區域中分配的靜態字段變量。 當類被卸載時,該靜態字段的內存也可以被GC垃圾收集。

如果該字段也是最終字段,即static final,則它會保留在類區域下的常量池中。

相關問題