GC作用域:方法区和堆
3.常见垃圾回收算法:
3.1引用计数由对象引用则加1
缺点:每次对对象赋值时都要维护引用计数器,且计数器本身也有一定消耗,比较难处理循环引用,JVM一般不采用这种方式
3.2复制:年轻代
1.eden、survivor form复制到surivivor to 年龄+1
首先当eden第一次触发Gc时,会将对象复制到survivorForm区,当eden第二次触发Gc时会扫描Eden和SurvivorForm区,对这两个区域进行垃圾回收,仍然存活的则放入survivorto区如果由对象年龄达到老年代则放入老年代()年龄+1
2.清理eden 和survivorfrom
然后清理eden和survivor from 也就是 复制后交换,谁空谁是to
3.survivor to survivor from 互换
最后 将survivor to 和 survivor from互换,原来 survivor to 成为下一次GC 的 survivor from 区部分对象会再to 和 from 中间多次交换 每次交换年龄+1如此15次以后最终还活着的则放入老年代。
优点:没有内存碎片
缺点:浪费空间,大对象复制比较耗时
java中什么样的对象能够进入老年代
1.大对象:所谓的大对象是指需要大量连续内存空间的java对象,最典型的大对象就是那种很长的字符串以及数组,大对象对虚拟机的内存分配就是坏消息,尤其是一些朝生夕灭的短命大对象,写程序时应避免。
2.长期存活的对象:虚拟机给每个对象定义了一个对象年龄(Age)计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1,。对象在Survivor区中每熬过一次Minor GC,年龄就增加1,当他的年龄增加到一定程度(默认是15岁), 就将会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold设置。
3.动态对象年龄判定:为了能更好地适应不同程度的内存状况,虚拟机并不是永远地要求对象的年龄必须达到了MaxTenuringThreshold才能晋升到老年代,如果在Survivor空间中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。
3.3标记清除(老生代)
优点:相比较起来内存消耗小,缺点: 内存碎片
3.4标记整理(老生代)
优点:消耗内存小,没有内存碎片,缺点需要移动对象