关于GC的三个问题

哪些内存需要垃圾回收?
java虚拟机栈、本地方法栈、程序计数器的内存都是随线程生随线程灭,只需要关注堆和方法区的垃圾回收
java堆中哪些对象需要回收:在GC Roots之间没有可达引用链
哪些对象可以作为GC Root:
    虚拟机栈中的引用的对象
    本地方法中的引用的对象
    方法区类型成员变量引用的对象
    方法区中常量引用的对象
    Java虚拟机内部的引用,如基本数据类型的Class对象、常驻的异常对象、系统类加载器
    被同步锁(synchronize)持有的对象
    反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等


方法区主要回收两部分内容:废弃的常量和不再使用的类型,回收效率较低。废弃的常量指的是没有对象引用的常量,不再使用的类型需要同时满足三个条件
1.没有任何类型实例
2.该类型的类加载器已被回收
3.该类型对应的java.lang,Class对象没有在任何地方引用

何时回收?
当对象到GC Roots之间不存在可达引用链被判定为回收对象时会被第一次标记,随后判断是否有必要执行对象的finallize方法(覆盖了finallize方法,且没有被执行过),如果有必要执行,则对象会被加入队列,虚拟机启动线程执行这些对象的finallize方法,如果在finallize方法中对象没有拯救自己(例如:将this赋值给类的成员变量),则会被第二次标记,被标记两次的对象将会被回收。


内存分配与回收策略:
对象优先在Eden区分配
    大多数情况下,对象在新生代Eden区分配,当Eden区没有足够内存分配时,虚拟机将发起Minor GC
大对象直接进入老年代
    大的对象需要连续的内存空间,为避免在新生代垃圾回收时,将大对象从Eden区复制到Survivor区高额的内存复制开销,可以通过-XX:PretenureSizeThreshold参数,指定大于一定值的对象直接进入老年代
长期存活的对象将进入老年代
    当Eden区的对象经过一次Minor GC 仍然存活,进入Survivor区,该对象年龄+1,对象每熬过一次Minor GC 年龄+1,当大于设定年龄时进入老年代
动态对象年龄判定
    当Survivor区相同年龄对象的总和大于Survivor空间的一半,年龄大于或者等于该年龄的对象将进入老年代
空间分配担保
    发生Minor GC之前,虚拟机会先检查老年代可用的连续空间是否大于新生代所有对象的总空间,如果大于则Minor GC是安全的
    如果小于,则判断是否允许承担担保失败风险,如果允许,则检查老年代可用的连续空间是否大于历次老年代的平均值,如果大于,将尝试Minor GC
    如果小于或者不允许承担风险,则进行Full GC

如何回收?
基于分代收集假说,将java堆分为新生代和老年代。
1.弱分代假说:大多数对象朝生夕灭
2.强分代假说:熬过越多次垃圾收集的对象越难以消亡

垃圾收集算法
标记-清除算法:标记需要回收的对象,统一清除
标记-复制算法:将内存区域分为两块,标记要清除的对象,将存活的对象复制到空闲的一块,将已使用的区域全部清除,适用于新生代
标记-整理算法;标记需要回收的对象,将存活的对象向内存一端移动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值