JVM-GC(hotspot虚拟机)机制

Java中相比于C和C++的有一项优点,就是垃圾回收机制由JVM自己完成,无需开发者担心,当然也会有例外情况会出现内存泄漏,但是从大体上来看,Java具有一套非常优秀的垃圾回收机制。

如何判断资源是否需要回收

就是 没有对象引用或对象不可达。

垃圾回收的范围

GC一般发生在方法区和堆中,栈中的内存离开作用范围就会自动释放。

常用算法-可达性算法

在Java中,我们可以通过可达性算法来判断该内存是否需要回收,什么是可达性算法呢?我们可以通过Root资源出发,遍历能达到的节点,那些不能达到的资源就是可以被回收释放的。
Root资源的定义如下:

在虚拟机栈帧中引用的对象,例如线程调用方法时,使用或产生的参数、局部变量、临时变量等。 在方法区中,类的引用类型静态变量或常量。
在本地方法栈中的JNI引用的对象,
在JVM内部的对象,例如基本数据类型的Class对象,一些常驻的异常对象(NullPointExcepiton),系统类加载器等。
所有synchronized同步锁的持有对象。 反映JVM内部情况的JMXBean、JVMTI注册的回调、本地代码缓存等

分代回收

在hotspot虚拟机中,采取的是分代回收的机制,会将堆中的内存空间分为三块,即eden区和两个survivor区,默认的内存大小是 8:1:1。

GC的类型

minorGC:新生代中的GC。
fullGC:堆区和方法区GC,会让java程序暂停(STW)等待回收结束。
majorGC:CMS垃圾收集器中实现,只回收老年代。
mixedGC:回收新生代和部分老年代,G1收集器中实现。

标记-清除算法

标记-清除算法,会扫描GCroots下被引用的对象,打上存活或清除的标记,然后将标记上的对象清除或保留,然而这样的操作省略的整理碎片化内存空间的操作,容易导致内存碎片化,也因此效率比标记-整理高许多。

标记-复制算法

复制算法也就是将内存区域分成两部分,也同样从GCroots出发,将存活的对象打上标记,然后批量转移到另一片区域,将之前的内存区域中的对象全部删除,好处是效率高且不会导致内存碎片化。坏处是需要占用50%的内存空间作为转移的区域。hotspot中对复制算法进行了优化,也就是分代回收中的操作,将区域分为3份,eden区作为新生代,所有新创建的内存对象会存放在这里,也意味着新生代里的内存对象存活率极低,在eden区中触发GC时,会将eden区和一个survivor区标记的对象移到另一个survivor区中,然后清空之前存放的eden区和survivor区中的内存对象。这样做的好处显而易见是将原来复制算法的缺点进一步减少了。其中有几个点需要注意,需要保证其中一个survivor区是空的,算法中存在分配担保机制,如果一个内存对象大到超过survivor区的大小,就会直接存放到老年代中。在多次minorGC中存活下来的对象会被分配到老年代,默认是15次(年龄阈值设置,可以在JVM参数中修改)。

标记-整理算法

标记-整理算法也就是在标记-清除算法上的最后添加了整理内存空间的步骤,效率低但是能保证内存连续,不会浪费内存空间,适合存活率高的内存区间使用,也就是老年代中的回收算法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值