深入理解Java虛擬機-筆記(一)

基本概念:

1.程序計數器(Program Counter Register)是一款較小的內存空間,是當前線程所執行的字節碼的行號指示器。字節碼解釋器工作時通過改變計數器的值來選取下一條需要執行的字節碼指令,他是程序控制流的指示器。每條線程都有一個獨立的PCR,各條線程之間計數器互不影響,獨立存儲,屬於線程私有的內存。

2.Java虛擬機棧(Java Virtual Machine Stack):線程私有,描述Java方法執行的線程內存模型,每個方法被執行的時候,Java虛擬機都會同步創建一個棧幀(Stack Frame),用於存儲局部變量表、操作數棧、動態連接、方法出口等信息。每一個方法被調用直至執行完畢的過程,就對應着一個棧幀在虛擬棧中從入棧到出棧的過程。

        局部變量表:存放了編譯器可知的各種Java虛擬機基本數據類型(boolean、byte、char、short、int、float、long、double)、對象引用(reference類型,並不等同於對象本身,可能是一個指向對象起始地址的引用指針,也可能是指向一個代表對象的句柄或者其他與此對象相關的位置)和returnAddress類型(指向了一條字節碼指令的地址)。這些數據類型在局部變量表中的存儲空間以局部變量槽(Slot)來表示,64位長度的long和double類型的數據佔倆變量槽,其餘類型佔一個。所需內存空間在編譯器分配,在方法運行期間不會改變局部變量表的大小。

        如果線程請求的深度大於虛擬機所允許的深度,將拋出StackOverflowError異常;若Java虛擬機棧容量可以動態擴展,當棧擴展時無法申請到足夠的內存會拋出OutOfMemoryError異常。

3.本地方法棧(Native Method Stacks):類似虛擬機棧作用,區別是虛擬機棧爲虛擬機執行Java方法(字節碼)服務,而本地方法棧則是爲虛擬機使用到的本地(Native)方法服務。也會在棧深度溢出或棧擴展失敗時分別拋出StackOverflowError和OutOfMemoryError異常。

4.Java堆(Java Heap)是虛擬機所管理的內存中最大的一塊,被所有線程共享,在虛擬機啓動時創建,唯一目的是存放對象實例。是垃圾收集器管理的內存區域,也被稱作GC(Garbage Collected)堆。

    如果從分配內存的角度看,所有線程共享的Java堆中可以劃分出多個線程私有的分配緩衝區(Thread Local Allocation Buffer,TLAB),以提升對象分配時的效率。

    Java堆可以處於物理上不連續的內存空間中,但在邏輯上它應該被視爲連續的。既可以被實現成固定大小的,也可以是可擴展的,當前主流Java虛擬機都是按照可擴展來實現的(通過參數-Xmx 和 -Xms設定)。若在堆中沒有內存完成實力分配,且堆也無法再擴展時,會拋出OOM異常。

5.方法區(Method Area):線程共享的內存區域,用於存儲已被虛擬機加載的類型信息、常量、靜態變量、即時編譯器編譯後的代碼緩存等數據。別名----“非堆(Non-Heap)”,區分於Java堆。也不需要連續的內存,可選固定大小和可擴展,也可以選擇不是想垃圾收集。這個區域的內存回收目標主要是針對常量池的回收和對類型的卸載。

    運行時常量池(Runtime Constant Pool):是方法區的一部分。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池表(Constant Pool Table),用於存放編譯期生成的各種字面量與符號引用,這部分內容將在類加載後存放到方法區的運行時常量池中。相對於Class文件常量池的另外一個重要特徵是具備動態性,Java語言並不要求常量一定只有編譯期才能產生,即並非預置入Class文件中常量池的內容才能進入方法區運行時常量池,運行期間也可以將新的常量放入池中,用的比較多的是String類的intern()方法。

6.直接內存(Direct Memory):不是虛擬機運行時數據區的一部分,可能會導致OOM,不會受到Java堆大小的限制,會受到本機總內存(包括物理內存、SWAP分區或者分頁文件)大小以及處理器尋址空間的限制。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章