方法区:保存已经被虚拟机加载的类元信息(类的字段,方法,接口,父类),运行时的static,final,字符串常量String,都放在这里。并不是一开始就全部加在,JVM运行过程中发现某个类要用class2,方法区里没有,那么就去检索查找class2.class文件,加载到jvm
虚拟机栈:主要是线程运行方法的区域。每一个线程创建以后都会执行自己的方法逻辑,那么运行的先后顺序就记录在虚拟机栈里面,所以这个是线程私有的。每一个方法都对应一个栈帧,方法顺序就推入到栈里面先入后出。
栈帧里面存着啥:变量的数据,方法执行完后返回数据存放的地址,操作数栈,动态链接(后边俩还不了解)
本地方法栈:java有的时候要和系统底层交互,就要用到C。本地方法栈是为了java调用本地C/C++方法。
程序计数器:当前线程所执行字节码的行号指示器。虚拟机栈是为了记录方法的嵌套调用啥的,这个计数器是为了标记当前程序执行到哪一行了,比如我切线程了,过了一会回来了,就靠这个找到我从哪里开始接着执行。
堆:主要存放创建的对象数据
堆内存里面分为新生代,老年代。
JVM中大部分对象都是一次性的,可能就用一次。如果所有对象都保存着所有对象就太亏了。新建对象放在新生代,经过多次GC后放入老年代。
然而直接放呢,会出现碎片化的内存空间。所以随着改进变成了:新生代(eden区,survior(s1,s2))老年代。
流程:
v1.0:一个新对象创建完了,就会放到eden区,运行一段时间GC开始标记,这时还存活的的对象就复制到了survior区,eden区清零。
v2.0:因为不可能直接一次就进老年代,所以survior里面也会有要清除的对象,那么也会面临内存碎片。将其再度划分为s1,s2。eden区进入s1区,此时s2空的。过一段时间后s1中还活的对象复制到s2中,s1清空,永远有个可以用的空白区域。



