簡要介紹Java的記憶體區域:運行時數據區域HotSpot虛擬機對象一、概覽二、運行時數據區域2.1 程式計數器Program Counter Register,代表當前線程所執行的位元組碼的行號指示器,操作系統中的PC,這兩個是一個概念。執行時就是通過改變這個計數器來選取下一條需要執行的位元組碼指令。J...
簡要介紹Java的記憶體區域:
- 運行時數據區域
- HotSpot虛擬機對象
一、概覽
二、運行時數據區域
2.1 程式計數器
Program Counter Register,代表當前線程所執行的位元組碼的行號指示器,操作系統中的PC,這兩個是一個概念。執行時就是通過改變這個計數器來選取下一條需要執行的位元組碼指令。Java支持多線程,所以每個線程有自己獨享的PC,類似於操作系統線程表中的一個屬性。
2.2 Java虛擬機棧
和PC一樣,是線程私有的,和線程的生命周期一樣。虛擬機棧描述的是Java方法執行的記憶體模型,每個方法在執行的時候都會創建一個棧楨(Stack frame),用與存儲局部變數,操作數、動態鏈接、方法出口等信息。局部變數放在棧中的局部變數表中,該表中存放了編譯器可知的基本數據類型(int。float,string。。)和對象的引用(reference)。
2.3 本地方法棧
Native Method Stack與Java虛擬機棧的作用非常相似,不過用於為虛擬機調用到的Native方法服務。
2.4 Java堆
Java堆被所有線程所共用,是Java程式的記憶體,在虛擬機啟動時創建,該記憶體區域的目的就是存放對象實例。Java堆是垃圾回收器(GC)管理的主要區域。
2.5 方法區
Method Area各個線程共用的區域,它用於存儲已被虛擬機載入的類信息、常量、靜態變數、即時編譯器編譯後的代碼等數據,
方法區內有一塊特殊的區域叫運行時常量池(Runtime Constant Pool),用於存放編譯時生成的各種字面量和符號引用(字元串)
2.6 直接記憶體
直接記憶體不是虛擬機運行時的一部分,但是會影響到Java堆的大小
三、HOTSPOT中虛擬機對象
3.1 對象的創建
Java是一門面向對象語言,對象的創建是通過new關鍵字來完成的。主要步驟:
- 先去方法區檢查類是否被載入
- 沒有載入則先載入類到方法區
- 為對象分配記憶體(類被載入後所需要的空間是已知的)
- 分配記憶體併發控制(仿製同一塊記憶體被分配給多個對象)
- 將所分配的記憶體空間初始化為0
- 將對象的基本信息(屬於那個類,對象哈希碼,GC代領等)放在對象頭中(Object Header)
- 至此新對象已經產生
- 調用Init方法,對對象的屬性按照程式員的想法進行賦值
3.2 對象記憶體佈局
對象在記憶體中主要分三塊:
- 對象頭(Header):第一部分存儲對象自身的數據,如哈希碼,GC代齡等,另外一部分是類型指針,虛擬機通過這個指針來確定這個對象是那個類的實例
- 實例數據(Instance Data):對象真正存儲的有效信息,程式代碼中定義的各種欄位的內容,父類中定義的也會被繼承下來。
- 對齊填充(Padding):沒有特殊意義,占位符,對象的大小必須是8位元組的整數倍。
3.3 對象的訪問定位
建立對象是為了使用對象,java程式需要通過存儲在棧上的reference數據來操作對上的具體對象,reference類型是一個指向對象的引用,並沒有定義這個歌引用該通過何種方式去定位、訪問堆中對象的具體位置,所以對象訪問方式也是取決於虛擬機的實現方式而定,目前主流有兩種:
1. 使用句柄訪問對象
使用句柄的好處是句柄穩定,當對象被移動(GC後)時只改變句柄中的實例數據指針,而Reference本事不需要修改。
2. 使用指針訪問對象
使用直接指針的最大好處就是速度更快,節省了一次指針定位的時間開銷。