JVM垃圾回收机制
1,哪些内存需要回收?
JVM内存结构包括五大区域:程序计数器,JVM栈,本地方法栈,堆区,方法区;
其中程序计数器,JVM栈,本地方法栈3个区域随线程而生,随线程而灭,
因此这几个区域的内存分配和回收都具备确定性,不需要过多考虑回收的问题,
因为方法结束或者线程结束时,内存自然就跟着回收了。
java堆区和方法区不一样,这部分的内存分配和回收时动态的。
垃圾回收器在对堆区和方法区回收前,要判断哪些对象可以被回收,
这就要用判断对象是否存活的算法。
引用计数算法:
在这种方法中,堆中每个对象实例都有一个引用计数。
当对象被创建时,给对象实例分配一个变量,该变量计数设置为1。
当把这个对象赋值给其他任何一个变量时,计数加1。
但当一个对象实例的某个引用超过了生命周期或者被设置为一个新值时,对象实例的引用计数器减1
任何引用计数器为0的对象实例可以被当作垃圾收集。
当一个对象实例被垃圾收集时,它引用的任何对象实例的引用计数器减1。
优点:引用计数收集器可以很快的执行,交织在程序运行中。对程序需要不被长时间打断的实时环境比较有利。
缺点:无法检测出循环引用。如父对象有一个对子对象的引用,子对象反过来引用父对象。这样,他们的引用计数永远不可能为0。
可达性分析算法:
程序把所有的引用关系看作一张图,从一个节点GC ROOT开始,寻找对应的引用节点,找到这个节点以后,
继续寻找这个节点的引用节点。当所有的引用节点寻找完毕之后,剩余的节点被认为是没有被引用到的节点,
即无用的节点,被判定为是可回收的对象。
java中,可作为GC Roots的对象包括:
a,虚拟机栈中引用的对象
b,方法区中类静态属性引用的对象
c,方法区中常量引用的对象
d,本地方法栈中JNI(Native方法)引用的对象
Java中引用分为:强引用、软引用、弱引用、虚引用
方法区如何判断是否需要回收?
方法区回收内容:废弃常量和无用的类
废弃常量用可达性分析算法判断
常用的垃圾收集算法:
1,标记-清除算法
2,复制算法
3,标记-整理算法
4,分代收集算法
4.1,年轻代的回收算法
4.2,年老代的回收算法
4.3,持久化的回收算法
常见垃圾收集器
Serial收集器
Serial Old收集器
GC什么时候被触发的?
1,Scavenge GC:
新对象生成时,Eden申请空间失败会触发Scavenge GC
2,Full GC:
2.1年老代被写满
2.2持久代被写满
2.3System.GC显式调用
2.4上一次GC之后Heap的各域分配策略动态变化