1. 程式人生 > >JVM虛擬機器記憶體簡析(一)

JVM虛擬機器記憶體簡析(一)

1.程式計數器

1.1 程式計數器在記憶體中佔用較小的一塊記憶體,主要作用是記錄當前執行緒執行的程式的位元組碼的地址。
1.2 各個執行緒的程式計數器是獨立儲存互不干涉的。
1.3 如果執行緒執行的是一個Java方法,程式計數器指向虛擬機器中該程式位元組碼的地址;
    如果執行的是Native方法,則這個計數器為Undefined。

2.Java虛擬機器棧

2.1 虛擬機器棧用來描述Java方法執行的記憶體模型,每個Java方法執行時都會建立一個棧幀,用來儲存區域性變數、操作棧、動態連結、方法出口等。
    每一個方法呼叫到執行完畢都對應了一個棧幀在虛擬機器棧中從入棧到出棧的過程。    
2.2 區域性變量表存放了編譯器可知的基本資料型別、物件引用型別、64位長度的long和double型別會佔兩個區域性變數空間(Slot)
2.3 虛擬機器棧也是執行緒私有的
2.4 虛擬機器棧中定義了兩種異常情況:StackOverflowError異常、OutOfMemoryError異常;
    2.4.1 StackOverflowError 會出現線上程請求的深度大於虛擬機器允許的深度時
    2.4.2 OutOfMemoryError 會出現在當需要記憶體擴充套件時,虛擬機器無法申請到足夠的記憶體時

3.本地方法棧

3.1 本地方法棧和虛擬機器棧類似,前者是為本地Native方法服務,而後者是為Java方法服務。
3.2 本地方法棧也包括上述兩種異常情況

4.Java堆

4.1 Java堆是JVM管理的最大的一塊記憶體區域,也是被所有線層共享的一塊區域,在虛擬機器啟動時建立。
4.2 該區域的唯一作用就是存放物件例項
4.3 該區域也是GC工作的主要區域,所以很多時候也被叫做GC堆。
4.4 Java堆可以存在於物理上不連續的記憶體中,邏輯上連續即可。

5.方法區

5.1 多個執行緒共享的記憶體空間,用於儲存已經被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼資料等。
5.2 對於sun的HotSpot虛擬機器來說,方法區也被叫做永久帶(Permanent Generation)
5.3 異常情況:OutOfMemoryError

6.執行時常量池

6.1 是方法區的一部分,用於存放編譯器生成的各種字面量和符號引用
    6.1.1 符號引用:就是在位元組碼檔案中以一組符號來表示所引用的目標,比如Student類中引用了Teacher類,
        但是實際上Student並不知道Teacher的地址在哪於是可以使用一組符號來表示Teacher的引用。
    6.1.2 直接引用:與符號引用對應的就是直接引用了;
        直接引用可以是一個直接指向目標的指標(指向Class物件,類變數、類方法的   直接引用可能是指向方法區的指標)
        或者是一個相對偏移量(指向例項變數例項方法的直接引用)
        或者是間接定位的控制代碼

6.2 執行時常量池是動態的,不僅是編譯器的常量,執行時的常量都可以放在池中,String類的intern()方法便是

6.3 OutOfMemoryError 異常情況

7.直接記憶體

7.1 直接記憶體並不是虛擬機器執行時記憶體的一部分,也不是Java定義的記憶體區域,但是經常被使用,也可能會出現OutOfMemoryError異常情況。
7.2 JDK1.4後引入了NIO(new Input/Output)支援了基於通道和緩衝區的I/O方式,可以直接通過Native函式分配堆外記憶體,好處是不用再Native堆和Java堆中來回複製資料。