JVM垃圾收集策略

JVM垃圾收集器有很多种,但常用垃圾算法就那么几种,作为一名java程序员,理解常用垃圾收集算法还是非常有必要的。

1.JVM如何判断一个对象是否可以回收?

引用计数算法
jvm没有采用这种算法,后面分析下为什么jvm不采用引用计数算法。

对于引用计数算法来说,会给对象添加一个引用计数器,初始值为0。每当有一个地方引用它时,计数器加1,当引用失效时,计数器减1。当计数器为0时,就表示此对象没有被引用,即可以被回收。

貌似python就使用了引用计数算法进行内存管理。但是引用计数算法有一个致命的缺陷——很难解决对象间的循环引用问题,这也是jvm没有采用这种算法的原因。

可达性分析算法
当一个对象到GC Roots没有任何引用相连接,用图论来说就是从GC Roots到这个对象不可达,则证明此对象是不可用的,说明此对象可以被GC。
这里写图片描述

在Java中,可以当做GC Root的对象有以下几种:
1、虚拟机(JVM)栈中的引用的对象
2、方法区中的类静态属性引用的对象
3、方法区中的常量引用的对象(主要指声明为final的常量值)
4、本地方法栈中JNI的引用的对象

垃圾收集算法

  1. 标记-清除算法
    首先标记处所有需要回收的对象,在标记完成后统一回收。后面介绍的算法都是在此基础上进行优化。
    问题:标记,清除的效率都不高,标记清除后会产生大量内存碎片。

这里写图片描述
2. 复制算法
将内存划分为大小相等的两块,每次只使用其中一块,垃圾收集的时候,将所有存活(不可回收)的对象复制到另一块内存中,然后把之前使用的那块内存一次清理掉。
优点:效率高,无碎片。
问题:可用内存缩小为一半,代价较高。
优化:JVM新生代采用的就是复制算法。不过新生代被分为了3块,一块较大的Eden区和两块较小的Surivor区。每次使用Eden和其中一块Surivor,垃圾收集的时候,将Eden和Surivor存活的对象复制到另一块Surivor中,之后使用Eden和另一块Surivor区。HotSpot默认Eden:Surivor = 8:1.
这里写图片描述
3. 标记-整理算法
在对象存活率较高时,复制算法需要复制的对象会非常多,效率将会变低。所以,老年代一般不直接使用复制算法,此时,标记-整理算法就派上用场了。
标记:标记所有存活的对象
整理:将所有存活的对象往内存一端移动,然后直接清理掉端边界之外的内存。
这里写图片描述
4. 分代收集算法
将Java堆分为新生代和老年代,新生代使用复制算法,老年代使用标记-清除或者标记-整理算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值