1.对象怎么判定已死:
1.对象引用计数法
每个对象都有一个引用计数器,当引用计数器归零时,即可判定对象已死。但是在互相引用的情况下,无法判定他们是否已死。
2.图论(节点不可达)
从GC root对象开始,如果发现有一个点,或者一个区域不可达,即判定这个区域的对象已死。
GC ROOT对象:
1.方法区静态变量的对象引用的对象。
2.方法区常量引用的对象引用的对象。
3.方法栈中局部变量表中的对象引用的对象。
4.本地方法栈的对象引用的对象。
2.方法区回收:
1.常量回收
没其他地方引用这个字面量了。
2.类卸载(同时满足)
1>.这个类在程序没有任何实例的存在。
2>.类加载器被回收了。
3>.字节码对象没有被任何地方使用,没反射的功能存在了。
3.怎么回收?
回收算法:
1.标记清除
容易产生大量的碎片,内存利用率越来越低。
2.标记-复制-清除
内存划分为两等份,回收一份后,直接复制到另一份。解决碎片的问题,但是整个内存的利用效率太低。
3.标记-整理-清除
把存活对象,向内存的一边移动,然后进行边界之外的内存进行清除。方法区的 大多对象时长久存活的,一般选择整个方式。
4.分代复制算法
应用于堆这种有大量的朝生夕灭的对象的区域,新生代分为一个Eden区和两个survive区,比例8:1:1。第一次进行MinorGC回收时,存活的进行survive区,到达一定年龄或者条件时进入老年代。
永久区是方法区,年轻代和老年代是堆。
4.回收的策略:
1.对象优先分配Eden区,大对象直接进行老年代,长期存活的对象进入老年代。避免大对象在新生代拷贝浪费资源。特别是朝生夕灭的大对象。
2.年龄计数器,达到一定年龄即进入老年代。
3.动态判断年龄,当相同年龄的对象的值大于Surviver空间的一半,大于等于这个年龄 的对象进入老年代。
4.空间担保:
MinorGC后可能出现,存活对象大于survive空间的大小,那就需要老年代作为担保人。
在MinorGC前,判断前面进入老年代的平均值是否大于老年代剩下的值,大于FullGC,小于并且担保打开,进行MinorGC,否则上一步。如果担保失败,那再进行一次FullGC。
为了减少FullGC的次数。
从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC,对老年代GC称为Major GC,而Full GC是对整个堆来说的.