JVM垃圾收集

本文介绍了Java的垃圾收集机制,包括内存区域划分、垃圾定义、可达性分析算法以及引用计数算法。讲解了如何判断对象是否可回收,并探讨了 finalize 方法的作用。此外,还概述了常用的垃圾收集算法,如标记-清除、复制和标记-整理,分析了它们的适用场景和优缺点。
摘要由CSDN通过智能技术生成

JVM垃圾收集

简介

java有内存动态分配和垃圾收集(Garbage Collection GC)技术。内存主要分为JAVA堆、方法区,程序计数器、虚拟机栈、本地方法栈,后面三种区域的内存是线程私有的,随线程而生随线程而灭。垃圾收集器主要是堆java堆和方法区进行回收

什么是垃圾

垃圾是什么?垃圾收集器在对堆进行回收前,要判断哪些对象是'死去'了的。死去的即不可能再被任何途径使用的对象,怎么才能确定一个对象是否死去,这就涉及到垃圾判断算法。

垃圾判断算法

①引用计数算法

引用计数算法的实现简单,判断效率也很高。他的实现是这样的:给对象添加一个引用计数器,每当一个地方引用他,那么计数器+1;当引用失效时,计数器-1。当计数器为0则表示这个对象不再被使用。但是JAVA虚拟机中没有选用引用计数算法来管理内存,主要原因是,他无法解决对象间的循环引用。举个例子,当有两个对象personA、personB,他们都有一个属性partner。personA.partner = personB, personB.partner = personA。如果使用引用计数算法,那么这俩对象将无法被回收。

②可达性分析

这个算法的思路是通过一系列的称为GC Roots 的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链(Reference Chain)。当一个对象到GC Roots没有任何引用链相连时,则证明此对象时不可用的。如图右边的对象即时他们被互相引用但是他们没有GC Roots相连,那么这个时候说明他们已'死亡'。

java虚拟机的是通过可达性分析来判断对象是否存活的,在java中可座位GC Roots的对象包括以下机种:

  • 虚拟机栈中(栈帧中的本地变量表)引用的对象(方法参数、局部变量、临时变量)

  • 方法区中类静态属性引用的对象

  • 方法区中常量引用的对象

  • 本地方法栈中JNI引用的对象

  • 虚拟机内部引用的对象、入类异常、系统类加载器

  • 被同步锁持有的对象

这些作用GC Roots的对象,他们都是程序运行时的源头,程序正常运行必须依赖他们。与这些源头没有任何联系的对象,即可视为可回收对象。

垃圾的生与死

即使对象已经死去也不是立即会被回收。这时候他们暂时时“缓刑”的状态,如果对象覆盖了finalize()方法。那么可以在finalize中被拯救一次。被finalize方法所拯救的对象将会被放在一个名为F-Queue的队列之中。finalize()方法只会被系统调用一次,如果对象在下一次回收它的finalize方法不会被执行。 finalize()方法运行代价高昂,不确定性大,无法保证各个对象的调用顺序。《深入理解java虚拟机》的作者建议大家忘掉这个方法。使用try-finally可以更好、更即时。

垃圾收集算法

垃圾收集算法有三种实现思路:标记-清除算法、赋值算法、标记-整理算法

标记-清除算法

这是最基础的收集算法,后面的算法都是基于这种思路进行优化的。算法分为俩个阶段:首先标记出所有需要回收的对象,对标记完成后,统一进行清除。因为清楚的内存在空间上是不连续的所以在这种算法的收集下会出现很多零碎的空间,当要分配较大对象时,无法找到足够的连续内存而不得不再触发一次垃圾收集动作。

 

复制算法

复制算法多用于新生代,他将内存划分为两块,每次只用其中一块,内存回收时就将其中的一块存活的对象复制到另外一块上面。然后再把已使用过的内存空间一次清理掉就,这样不再需要考虑碎片等复杂情况问题,按顺序分配内存即可,实现简单,运行高效。 IBM公司专门研究表明,新生代的对象中98%是“朝生夕死”。将可用内存划分为一块较大的区域Eden,和两块较小的区域Survivor,Eden默认占空间的80%。每次只使用一块Eden和一块Survivor。只保留10%作为保留区域。我们无法保证每次回收都达到90%以上的内存,当Survivor空间不够用时,需要依赖老年代的内存进行分配担保,就是当Survivor无法容纳这些存活对象时,这些对象将用老年代内存进行存储。

 

标记-整理算法

当垃圾回收时存活对象较多时,复制算法的效率会很低,因为保留区域的空间是被浪费的,当存活对象较多时我们就要设计更多的空间给保留区域,这样浪费的内存也会更多。所以复制算法不适用于老年代。 根据老年代的特点,诞生了标记-整理算法。标记-整理算法的标记过程与标记清除算法相同,不同的在于第一步标记整理算法是将存活对象移至内存一端,然后清理掉端边界以外的内存。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值