2012-11-01 64 views
5

我想完全理解Java如何使用其內存安排。關於互聯網的討論非常混亂,有時互相矛盾,所以我找不到任何我可以信任的人。如果它與靜態,靜態方法,局部變量,線程,易失性等混合在一起,這件事情會變得非常複雜。所以我在考慮是否有一種方法可以讓我自己學習一些Java編碼實驗。一類MemoryTrack做這樣的事情,在Java中,有沒有一種方法可以跟蹤堆或棧中創建的變量,方法或類?

public myMethod(){ 
int i = 0; 
MemoryTrack.show(new myClass()); //print out "Heap at address 111" 
MemoryTrack.show(new myClass()); //print out "Heap at address 222" 
MemoryTrack.show(i); //print out "Stack at address 333" 
MemoryTrack.show("a static method"); //print out "stack at address 444" 
} 
+0

爲什麼不把它作爲答案? –

+1

在任何情況下,Java的一部分是你不應該關心堆棧上的內容以及堆棧上的內容 - 實際上,JIT有時會發現堆棧上可能存在的東西通常會繼續存在堆。 –

+0

@Zoltán:完成。 - – ignis

回答

7

使用內存中Section 2.5 of the Java Virtual Machine Specification描述。堆棧存儲堆棧幀(包含局部變量和部分結果)。堆是所有類實例和數組來自的地方。堆棧幀也可以從堆中分配(然後壓入堆棧)。還有方法區域和運行時常量池內存。細節在規格中詳細說明。

就監控內存使用情況而言,多個分析器都有相應的工具。要從程序內部進行監視,請查看MemoryMXBean課程(以及java.lang.management包中的相關課程)。它非常易於使用。雖然它可能不會給你聽起來像你想要的一切,但它可能是最好的東西。

3

規則很簡單:堆包含對象,堆棧包含局部變量和方法參數。對象字段位於堆中的對象內部。不知道靜態字段。方法和構造函數不存儲在堆棧中,也不存儲在堆中。線程和volatile不重要。

方法調用在堆棧上。每個都有一個保留的空間,即堆棧幀,它包含本地變量和參數。

-1

您可能認爲Java中的所有變量都堆在一起。實際上它依賴於實現。

+2

實際上,它在[Java虛擬機規範](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5)中有很好的說明。唯一依賴於實現的特性是堆棧的結構,是否從堆中分配堆棧幀,以及OP的問題外圍的其他一些問題。 –

+0

我聽說他們在Java 7或Java 6中改變了一些東西...... – Dims

+1

上面的鏈接是針對SE 7的。[SE 5規範](http://docs.oracle.com/javase/specs/jvms /se5.0/html/Overview.doc.html#1732)與此主題具有幾乎相同的語言。 –

1

兩件事情你需要知道的

  • 它並不像你想象的那麼複雜。
  • 99%的時間並不重要。

變量總是在堆棧中。

對象始終在堆上。 (有例外,但我不擔心他們)

方法和類總是在燙髮。

在HotSpot/OpenJDK JVM中,靜態字段被收集在類的單例對象中。如果您執行堆轉儲,則可以看到該實例。其他JVM可能會以不同方式做到這一點。

類MemoryTrack做這樣的事情,

這種方法不會做任何事情作爲一個參數總是在棧上和對象有用它是指將永遠是在堆上。您無法以標準方式獲取對象的內存位置,如果它可以隨時更改,則不太可能有用。

相關問題