JVM
JVM主要包括:程序计数器(Program Counter),Java堆(Heap),Java虚拟机栈(Stack),本地方法栈(Native Stack),方法区(Method Area)
这里我主要介绍 堆 栈 与 方法区:
方法区:
主要存放 代码片段,静态代码块,static修饰的变量,常量。
注意一下:
1.其中静态代码块,既static{}
里面的将优先于其他代码执行。
2.常量池在java 1.8版本之前是在方法区中,但在Java 1.8之后被移至堆中。
堆
主要存放对象。
注意:
堆在存放对象是会在对象中添一个地址,该地址为该存放对象的首地址。
栈
栈往往很小
遵循着先进后出,后进先出的原则。
里面有方法栈帧与局部变量。
一个.java文件先被编译为.class文件,然后就进入到JVM里面,最先进入方法区,会记录里里面的各种方法,并且会执行static{}里面的代码。同时会记录里面的常量(这里面的常量不只用户定义的常量。例如System.out.println("sssssss");
中的sssssss就会被自动定义并储存在常量池。紧接着是栈。栈的第一步几乎全为main方法压栈,当在main方法中引用另一个方法时,就会由那一个方法压在main栈帧之上:当执行完这一个方法时,该栈帧就会被弹出,才会继续执行main方法。(当然如果该方法内又引用其他方法,其他方法同样会进栈,压在上一个方法之上)。接着说说在方法中定义的对象与局部变量:例如在main方法中定义了一个Person对象,那么就会在堆中分配相应的空间,该空间常常会比代码所写的空间大一些。因为会在该对象里面末尾定义一个叫this
的地址,该地址为对象的的首地址。而在栈中仅会储存这个地址指向该对象。当该栈帧被执行完后被弹栈,那么没有指向在堆中对象时,该对象就会被GC(也就是被清除,回收空间)。在反复的弹栈与压栈后,当main方法被弹出时就完成的整个程序的执行。(本人还是一个新手,对内存的理解仅到这种地步,如有错误,希望大家指出。)
(该图片为本人老师讲课时截的图,非本人所画)