一.內存分配。java虛擬機在運行的時候,將會包含以下運行時數據區域:
1.線程私有的部分:
程序計數器:可以看成是當前線程所執行字節碼的行號指示器。字節碼解釋器就是通過改變這個計數器的值來確定下一條字節碼指令。
虛擬機棧:虛擬機棧爲虛擬機使用的java方法(也就是字節碼)服務。用於存儲局部變量表,操作數棧,動態鏈接,方法出口等信息。局部變量表存放了基本數據類型(short,int,float,long,double,byte,char,boolean),以及對象的引用(reference類型,它不等同於對象本身,可能是一個指向對象起始地址的引用指針,也可能是指向代表對象的句柄的位置)
本地方法棧:本地方法棧爲虛擬機使用到的native方法服務。
2.線程共享的部分:
java堆:用來爲創建的對象分配內存。
方法區:用於存儲已被虛擬機加載的類信息,常量,靜態變量,即使編譯器編譯後的代碼等數據。
二.對象的創建
1.內存分配
2.將除了對象頭的空間都分配爲零值
3.對對象進行必要的設置,這部分信息存儲在對象頭中
4.執行對象的init方法,按照程序的指令初始化對象
三.對象的內存佈局
分爲三部分:
1.對象頭:一是存儲對象自身的運行時數據,二是存儲指向對象的類元數據的指針,虛擬機通過這個指針來判斷這個對象是哪個類的實例;
2.實例數據:這部分纔是對象真正存儲的有效信息;
3.對齊填充:HotSpot虛擬機要求對象的起始位置必須是8的倍數,而對象頭部分正好是8的倍數,當實例數據不是8的倍數時,由對其填充部分補齊。
四.對象的訪問定位
目前的主流方法有使用句柄和直接指針兩種方式
1.使用句柄:使用這種方法,在java堆中會分配一部分內存空間作爲句柄池,棧中的reference引用指向堆中對應的句柄,而句柄包含了對象的實例數據和對象的類型數據各自的地址信息。
2.直接指針:棧中的reference引用直接指向堆中的對象實例,而實例中會有一部分信息記錄對象對應的類型數據的地址。HotSpot使用的該種方式執行對象訪問。