這篇主要是對java 中內存模型的初步認識,做爲了解類初始化過程,垃圾回收算法的基礎(上面的圖是導來的)java
程序計數器(線程私有的)c++
java虛擬機的多線程是經過線程輪流切換來實現的,爲了使線程在切換後還能恢復到正確的執行位置,每個線程都須要一個獨立的程序計數器。它用來記錄下一個要運行的指令算法
2.Java虛擬機棧windows
虛擬機的棧也是線程私有的,虛擬機棧描述的是Java方法執行的內存模型:每一個方法在執行時都會建立一個棧幀用來存儲定義在方法內部的局部變量,操做數棧、動態連接、方法出口、返回類型等信息。方法從調用到執行,至關於棧幀在虛擬機棧中的入棧和出棧的過程。數組
其中局部變量表,存儲的是java8個基本類型的數據,對象的引用(reference)多線程
3.本地方法棧
jvm
JNI(Java native interface)java的本地方法調用接口,主要是爲java調用windows系統的c\c++的方法提供服務。在不一樣的虛擬集中,把java虛擬機棧和本地方法棧和二位一
函數
4.Java 堆spa
java虛擬機中管理最大的一塊空間,幾乎全部的對象實例和數組都分配在java的堆中,供其它線程使用,因此java堆是線程共享的。Java堆仍是垃圾收集器的主要管理的區域,成爲GC堆(Garbage Collection Heap),因爲如今的收集器都採用分代收集的算法,因此堆大體能夠分爲新生代,老年代,永久代,其中新生代是垃圾收集器的主要收集的區域,基本上清理對象達到70%以上,但也不失絕對的。線程
新生代的比例大體又分爲Eden空間,From Survivor空間,To Survivor 空間,通常的分配比例爲8:1:1,因此新生代每次能夠分配的空間是新生代空間的90%,在對90%的空間進行第一次GC時,對於還存活的對象實例和數組,虛擬機會把這些對象實例復值到To survivor 的空間裏去,固然,當清理後剩餘大於10%時則須要老年代來幫忙。
這裏補充下對各類GC的區別,Minor GC、Major GC和Full GC
(1)Minor GC 主要是對新生代中的 Eden和Survivor區域進行內存回收
(2)Major GC 是清理永久代的空間
(3)Full GC是清理整個堆空間,包括了新生代,老年代和永久代
5.方法區
方法區也是線程共享的,用來存儲已經被加載的類的結構信息,例如常量,靜態變量,方法數據,構造函數和普通方法的字節碼內容。(本身的理解,不知道對不對)方法區是加載屬於類的一些信息(常量,靜態變量、方法等),而在堆中已經實例的對象是共享這些信息的,這些類的實例對象中持有的是對類信息的引用。咱們能夠寫代碼來驗證一下。
下面 類A中有一個靜態變量和一個普通的變量,2個A的實例化對象,假設2個實例化對象是持有對類A的靜態變量的引用,那麼當實例對象a修改靜態變量時,a1打印出來的也是同樣的值
public class jvmYongOld { private static final int _1MB=1024*1024; public static void main(String[] args) { A a=new A(); A a1=new A(); a.print(); a1.print(); a.a=4; a.print(); a1.print(); a.b=9; a.printb(); a1.printb(); } } class A{ static int a=3; int b=3; static void print(){ System.out.println("a="+a); } void printb(){ System.out.println("b="+b); } }
根據打印結果,上面的假設都是對的,也就是說,靜態變量,常量等信息都是屬於類的,類的實例對象只是持有對其的引用。
最後上一幅《深刻理解java虛擬機中》的圖片,能夠形象的表述下棧,堆,方法區的關係