一. jvm的内存模型分5个区域:
- 程序计数器:是线程私有的,用来记录当前线程的程序行号
因为多线程执行时,保证线程切换后可以恢复到正确的执行位置,线程私有,每个线程都有自己的程序计数器
2.虚拟机栈:就是传说的栈,线程私有,当一个方法执行时,会创建一个栈帧用于存储局部变量、操作数和方法出口等。一个方法被调用的过程,就是栈帧入栈和出栈的过程
当线程请求的栈帧深度大于栈允许的栈帧深度时,会报StackOverFlowError
3.本地方法栈:线程私有的,和虚拟机栈发挥的作用类似,当调用native方法时,使用的是本地方法栈
4.方法区:线程共享,用于存放类模板(结构)信息、静态变量和常量等
5.堆:线程共享,用户存放对象的实例,是垃圾回收的主要区域
二. 垃圾回收:
1.垃圾回收主要是针对堆内存进行回收,采用可达性分析算法,找到需要回收的对象;采用分代收集算法收集对象。
2.可达性分析算法:将一些对象作为GC ROOTS,其他对象与GC ROOTS之间如果不存在引用链,则需要回收。
可以作为GC ROOTS的对象有一下四种:
1).方法区中的静态变量引用的对象 2).方法区中的常量引用的对象 3).栈帧中局部变量中的引用对象 4).本地方法栈中的native方法引用的对象
3.分代收集算法分3种:
1).复制算法——新生代使用 2).标记清除算法——老年代使用 3).标记整理算法——老年代使用
堆的内存空间分为新生代和老年代,(新生代又进一步分为Eden区、S0(survivor)区和S1(survivor)区,内存比例 8:1:1)
对象是从Eden区产生的,当Eden区分配满的时候触发young GC,98%的对象都会被回收,不能被回收的对象将被复制到S0区,对象年龄+1,(对象头中存有年龄标志位,占4位,最大值正好是15,所以当对象年龄到达15岁时会晋升到老年代);当老年代中空间不足时,会触发Full GC,stop the world,即除GC线程外,所有线程都会停止工作,供可达性分析算法查找可以回收的对象。