天天看點

【Java -- 虛拟機】運作時資料區域

【Java -- 虛拟機】運作時資料區域

程式計數器

記錄正在執行的虛拟機位元組碼指令的位址(如果正在執行的是本地方法則為空)。

Java 虛拟機棧

每個 Java 方法在執行的同時會建立一個棧幀用于存儲局部變量表、操作數棧、常量池引用等資訊。從方法調用直至執行完成的過程,對應着一個棧幀在 Java 虛拟機棧中入棧和出棧的過程。

可以通過 -Xss 這個虛拟機參數來指定每個線程的 Java 虛拟機棧記憶體大小,在 JDK 1.4 中預設為 256K,而在 JDK 1.5+ 預設為 1M:

java -Xss2M HackTheJava      

該區域可能抛出以下異常:

  • 當線程請求的棧深度超過最大值,會抛出 StackOverflowError 異常;
  • 棧進行動态擴充時如果無法申請到足夠記憶體,會抛出 OutOfMemoryError 異常。

本地方法棧

本地方法棧與 Java 虛拟機棧類似,它們之間的差別隻不過是本地方法棧為本地方法服務。

本地方法一般是用其它語言(C、C++ 或彙編語言等)編寫的,并且被編譯為基于本機硬體和作業系統的程式,對待這些方法需要特别處理。

所有對象都在這裡配置設定記憶體,是垃圾收集的主要區域(“GC 堆”)。

現代的垃圾收集器基本都是采用分代收集算法,其主要的思想是針對不同類型的對象采取不同的垃圾回收算法。可以将堆分成兩塊:

  • 新生代(Young Generation)
  • 老年代(Old Generation)

    堆不需要連續記憶體,并且可以動态增加其記憶體,增加失敗會抛出 OutOfMemoryError 異常。

可以通過 -Xms 和 -Xmx 這兩個虛拟機參數來指定一個程式的堆記憶體大小,第一個參數設定初始值,第二個參數設定最大值。

java -Xms1M -Xmx2M HackTheJava      

方法區

用于存放已被加載的類資訊、常量、靜态變量、即時編譯器編譯後的代碼等資料。

和堆一樣不需要連續的記憶體,并且可以動态擴充,動态擴充失敗一樣會抛出 OutOfMemoryError 異常。

對這塊區域進行垃圾回收的主要目标是對常量池的回收和對類的解除安裝,但是一般比較難實作。

HotSpot 虛拟機把它當成永久代來進行垃圾回收。但很難确定永久代的大小,因為它受到很多因素影響,并且每次 Full GC 之後永久代的大小都會改變,是以經常會抛出 OutOfMemoryError 異常。為了更容易管理方法區,從 JDK 1.8 開始,移除永久代,并把方法區移至元空間,它位于本地記憶體中,而不是虛拟機記憶體中。

方法區是一個 JVM 規範,永久代與元空間都是其一種實作方式。在 JDK 1.8 之後,原來永久代的資料被分到了堆和元空間中。元空間存儲類的元資訊,靜态變量和常量池等放入堆中。

運作時常量池

運作時常量池是方法區的一部分。

Class 檔案中的常量池(編譯器生成的字面量和符号引用)會在類加載後被放入這個區域。

直接記憶體

上一篇: URAL 1141
下一篇: Honeyd學習