##jvm做三个步骤
##类装载器
##字节码效验器
##解释器
jvm的内存模型
程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;
Java 虚拟机栈(Java Virtual Machine Stacks):用于存储局部变量表、操作数栈、动态链接、方法出口等信息;
本地方法栈(Native Method Stack):与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java 方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;
Java 堆(Java Heap):Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存;
方法区(Methed Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据
堆栈的区别?
功能方面:堆是用来存放对象的,栈是用来执行程序的;
共享性:堆是线程共享的,栈是线程私有的;
空间大小:堆大小远远大于栈;
JVM内存大小
JVM内存大小 = 年轻代大小 + 年老代大小 + 持久代大小
年轻代:又分为伊甸园、存活区(from、to)
所有新生成的对象首先都是放在年轻代;
老年代:在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到老年代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象;
持久代:用于存放静态文件;
垃圾回收流程
新的对象保存在伊甸园,伊甸园不足,则触发年轻代垃圾回收;
再判断伊甸园内存是否足够,不够查看存活区,如果存活区足够,则将伊甸园部分对象保存在存活区,自己留在伊甸园;
如果存活区内存不够,则查看老年代内存是否足够,足够则依次迁移存活区到老年代,伊甸园到存活区,自己留在伊甸园;
如果老年代内存都不足,则进行全局gc,清理完之后依然不足,则抛出outofmemory异常 ---- 这个时候需要根据异常的信息进行相应的修改jvm参数;
垃圾收集算法
标记-清除算法:标记无用对象,然后进行清除回收。缺点:效率不高,无法清除垃圾碎片;
复制算法:按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。缺点:内存使用率不高,只有原来的一半;
标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存;
分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代,新生代基本采用复制算法,老年代采用标记整理算法;