JVM主要由類加載器子系統、運行時數據區(內存空間)、執行引擎以及與本地方法接口等組成。其中運行時數據區又由方法區Method Area、堆Heap、Java stack、PC寄存器、本地方法棧組成。
堆區:
1.存儲的全部是對象,每個對象都包含一個與之對應的class的信息。(class的目的是得到操作指令)
2.jvm只有堆區(heap)和方法區(下面)被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身.
3.一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。
棧區:
1.每個線程包含一個棧區,棧中只保存基礎數據類型的對象和自定義對象的引用(不是對象),對象都存放在堆區中
2.每個棧中的數據(原始類型和對象引用)都是私有的,其他棧不能訪問。
3.棧分為3個部分:基本類型變量區、執行環境上下文、操作指令區(存放操作指令)。
4.由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等.
靜態區/方法區:
1.方法區又叫靜態區,跟堆一樣,被所有的線程共享。方法區包含所有的class和static變量。
2.方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變量。
3.全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。
方法區
類型信息和類的靜態變量都存儲在方法區中。方法區中對於每個類存儲了以下數據:
a.類及其父類的全限定名(java.lang.Object沒有父類)
b.類的類型(Class or Interface)
c.訪問修飾符(public, abstract, final)
d.實現的接口的全限定名的列表
e.常量池
f.字段信息
g.方法信息
h.靜態變量
i.ClassLoader引用
j.Class引用
可見類的所有信息都存儲在方法區中。由於方法區是所有線程共享的,所以必須保證線程安全,舉例來說,如果兩個類同時要加載一個尚未被加載的類,那么一個類會請求它的ClassLoader去加載需要的類,另一個類只能等待而不會重復加載。
此外為了加快調用方法的速度,通常還會為每個非抽象類創建私有的方法表,方法表是一個數組,存放了實例可能被調用的實例方法的直接引用。方法表對於多態有非常重要的意義,具體可以參照《淺談多態機制的意義及實現》一文中“多態的實現”一節。
在Sun JDK中,方法區對應了持久代(Permanent Generation),默認最小值為16MB,最大值為64MB。
http://blog.hesey.net/2011/04/introduction-to-java-virtual-machine.html