1、什么是垃圾?
没有任何引用指向的一个对象或多个对象(循环引用),就是垃圾。
2、如何定位垃圾?
定位垃圾有两种方法:
1、引用计数法:在创建对象的时候给对象添加一个引用计数器,每当对象引用的时候,计数器值加一,当引用失败时,计数器值减一,直到为零的时候就视为垃圾。引用计数器法实现简单,判断效率也比较高,但是最主要的原因是它很难解决循环引用。
2、可达性分析法:通过GC Root对象为起点,开始向下搜索,搜索所走的路径成为引用链,当一个对象没有任何引用链时,则证明对象是不可用的。
GC Root包括:虚拟机栈中引用的对象、方法区中静态变量引用的对象、方法区中常量引用的对象、本地方法栈中引用的对象
3、常见的垃圾回收算法:
1、标记清除算法(Mark Sweep):有两个不足,一个是效率问题,标记和清除的效率都不高;另一个是空间问题,标记清除之后产生大量的不连续的垃圾碎片。如果需要分配大对象是,无法分配,不得不触发另一次垃圾收集的动作。
2、复制算法(Copying):没有碎片产生,但是会浪费一块内存。
3、标记整理算法(Mark Compact):缺点效率比较低。
4、JVM内存分代模型(用于分代垃圾回收算法)
1、部分垃圾回收器使用的模型
2、新生代+老年代+永久代(1.7)/ 元空间(1.8)
永久代必须制定大小的限制,元空间可以设置,可以不设置,受限于物理内存。
3、字符串常量(1.7)永久代。(1.8)堆里。
4、新生代=Eden+2个survivor区
- YGC回收之后,大多数的对象会被回收,活着的进入s0
- Eden满了再次YGC,活着的对象Eden+s0 --》s1
- 再次YGC,Eden+s1--》s0
- 年龄足够大(默认15)--》老年代
- 大对象直接进入老年代
动态对象年龄判断:虚拟机不是永远的要求对象到达一定年龄时,才能晋升老年代。如果在survivor空间中的相同年龄的对象大小的总和大于survivor空间的一半,年龄大于或者等于该年龄的对象就可以直接就去老年代。
空间分配担保:在发生Minor gc以前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象的总空间,如果这个条件成立,那么Minor gc可以确保是安全的。如果不成立,则虚拟机hi查看handlepromotionfailure设置值是否允许担任失败,如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次Minor gc ,尽管这次minor gc 有风险的;如果小于或者handlepromotionfailure设置不允许冒险,那这时也要改为进行一次full gc