在瞭解jvm的結構以前,咱們有必要先來了解一下操做系統的內存基本結構:java
操做系統中的jvm程序員
爲何jvm的內存是分佈在操做系統的堆中呢??由於操做系統的棧是操做系統管理的,它隨時會被回收,因此若是jvm放在棧中,那java的一個null對象就很難肯定會被誰回收了,那gc的存在就一點意義都沒有了,而要對棧作到自動釋放也是jvm須要考慮的,因此放在堆中就最合適不過了。 操做系統+jvm的內存簡單佈局 算法
從上圖中,你能夠看到,jvm的內存結構竟然和操做系統的結構驚人的一致,再來看一個圖。看我下面紅色的標註jvm
你應該不難發現,原來jvm的設計的模型其實就是操做系統的模型,基於操做系統的角度,jvm也就是一個應用(java.exe/javaw.exe),而基於class文件來講,jvm就是個操做系統,而jvm的方法區,也就至關於操做系統的硬盤區,因此方法區也被叫作permanent區,由於這個單詞是永久的意思,也就是永久區。而java棧和操做系統棧是一致的,不管是生長方向仍是管理的方式,至於堆嘛,雖然概念上一致目標也一致,分配內存的方式也一直(new,或者malloc等等),可是因爲他們的管理方式不一樣,jvm是gc回收,而操做系統是程序員手動釋放,因此在算法上有不少的差別. 看下面的圖。 佈局
將這個圖和上面的圖對比多了什麼?沒錯,多了一個pc寄存器,所謂pc寄存器,不管是在虛擬機中仍是在咱們虛擬機所寄宿的操做系統中功能目的是一致的,計算機上的pc寄存器是計算機上的硬件,原本就是屬於計算機,計算機用pc寄存器來存放「僞指令」或地址,而相對於虛擬機,pc寄存器它表現爲一塊內存(一個字長,虛擬機要求字長最小爲32位),虛擬機的pc寄存器的功能也是存放僞指令,更確切的說存放的是將要執行指令的地址,它甚至能夠是操做系統指令的本地地址,當虛擬機正在執行的方法是一個本地方法的時候,jvm的pc寄存器存儲的值是undefined,因此你如今應該很明確的知道,虛擬機的pc寄存器是用於存放下一條將要執行的指令的地址(字節碼流)。 操作系統
這個圖是要告訴你,當一個classLoder啓動的時候,classLoader的生存地點在jvm中的堆,而後它會去主機硬盤上將A.class裝載到jvm的方法區,方法區中的這個字節文件會被虛擬機拿來new A字節碼(),而後在堆內存生成了一個A字節碼的對象,而後A字節碼這個內存文件有兩個引用一個指向A的class對象,一個指向加載本身的classLoader設計
以下圖。對象