【JVM】内存回收

1、哪些资源需要回收
程序计数器,虚拟机栈,本地方法栈,由线程而生,随线程而灭,栈中的栈帧随着方法的进入顺序执行,入栈出栈,栈帧内存大小在虚拟机编译期间确定的,当方法或者线程执行完毕后,就回收了,这三大模块无需关心。
Java堆以及方法区,这部分的内存的分配和回收都是动态的。
2、什么时候回收
判断对象是否存活算法
“GC Roots”的对象为起始点,搜索所经过的路径称为引用链,当一个对象到GC Roots没有任何引用跟它连接则证明对象是不可用的。
要真正宣告对象死亡需经过两个过程。
1.可达性分析后没有发现引用链
2.查看对象是否有finalize方法,如果有重写且在方法内完成自救[比如再建立引用],还是可以抢救一下,注意这边一个类的finalize只执行一次,这就会出现一样的代码第一次自救成功第二次失败的情况。[如果类重写finalize且还没调用过,会将这个对象放到一个叫做F-Queue的序列里,这边finalize不承诺一定会执行,这么做是因为如果里面死循环的话可能会时F-Queue队列处于等待,严重会导致内存崩溃,这是我们不希望看到的。]
GCRoots:
a虚拟机栈中引用的对象
b方法区中类静态属性引用的对象
c方法区中的常量引用的对象
d本地方法栈中JNI隐痛的
3、怎么回收
标记/清除算法、复制算法、标记/整理算法
jvm采用分代收集算法对不同区域采用不同的回收算法。
新生代:采用复制算法(比较适合用于存活率低的内存区域),分为一块Eden空间和From Survivor、To Survivor,8:1:1;年龄值达到年龄阈值,移到老年代;
老年代:标记/清除算法或标记/整理算法(存活率高,没有额外空间给他做担保);
枚举根节点算法
可达性分析算法的弊端:
1.如果方法区几百兆,一个个检查里面的引用,将耗费大量资源
2.在分析时,需保证这个对象引用关系不再变化,否则结果将不准确
OopMap: 记录栈上本地变量到堆上对象的引用关系;safepoint安全点的时候更新OopMap数据,枚举根节点时,递归遍历每个栈帧的OopMap,就可以找到所有的GCRoots。OopMap可以避免全栈扫描,加快枚举根节点的速度,可以帮助HotSpot实现准确式GC。
安全点:
1:循环的末尾
2:方法临返回前/调用方法的call指令后
3:可能抛异常的位置
RememberedSet

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值