当前位置: 首页 新闻详细

java有哪些垃圾回收算法?JVM有哪些垃圾回收算法?

一、java有哪些垃圾回收算法?

常用的垃圾回收算法有:

(1).引用计数算法:

给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器都为0的对象就是不再被使用的,垃圾收集器将回收该对象使用的内存。

引用计数算法实现简单,效率很高,微软的COM技术、ActionScript、Python等都使用了引用计数算法进行内存管理,但是引用计数算法对于对象之间相互循环引用问题难以解决,因此java并没有使用引用计数算法。

(2).根搜索算法:

通过一系列的名为“GCRoot”的对象作为起点,从这些节点向下搜索,搜索所走过的路径称为引用链(ReferenceChain),当一个对象到GCRoot没有任何引用链相连时,则该对象不可达,该对象是不可使用的,垃圾收集器将回收其所占的内存。

主流的商用程序语言C#、java和Lisp都使用根搜素算法进行内存管理。

在java语言中,可作为GCRoot的对象包括以下几种对象:

a.java虚拟机栈(栈帧中的本地变量表)中的引用的对象。

b.方法区中的类静态属性引用的对象。

c.方法区中的常量引用的对象。

d.本地方法栈中JNI本地方法的引用对象。

java方法区在SunHotSpot虚拟机中被称为永久代,很多人认为该部分的内存是不用回收的,java虚拟机规范也没有对该部分内存的垃圾收集做规定,但是方法区中的废弃常量和无用的类还是需要回收以保证永久代不会发生内存溢出。

判断废弃常量的方法:如果常量池中的某个常量没有被任何引用所引用,则该常量是废弃常量。

判断无用的类:

(1).该类的所有实例都已经被回收,即java堆中不存在该类的实例对象。

(2).加载该类的类加载器已经被回收。

(3).该类所对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射机制访问该类的方法。

Java中常用的垃圾收集算法:

(1).标记-清除算法:

最基础的垃圾收集算法,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成之后统一回收掉所有被标记的对象。

标记-清除算法的缺点有两个:首先,效率问题,标记和清除效率都不高。其次,标记清除之后会产生大量的不连续的内存碎片,空间碎片太多会导致当程序需要为较大对象分配内存时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

(2).复制算法:

将可用内存按容量分成大小相等的两块,每次只使用其中一块,当这块内存使用完了,就将还存活的对象复制到另一块内存上去,然后把使用过的内存空间一次清理掉。这样使得每次都是对其中一块内存进行回收,内存分配时不用考虑内存碎片等复杂情况,只需要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。

垃圾回收算法实现代码

复制算法的缺点显而易见,可使用的内存降为原来一半。

(3).标记-整理算法:

标记-整理算法在标记-清除算法基础上做了改进,标记阶段是相同的标记出所有需要回收的对象,在标记完成之后不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,在移动过程中清理掉可回收的对象,这个过程叫做整理。

标记-整理算法相比标记-清除算法的优点是内存被整理以后不会产生大量不连续内存碎片问题。

复制算法在对象存活率高的情况下就要执行较多的复制操作,效率将会变低,而在对象存活率高的情况下使用标记-整理算法效率会大大提高。

(4).分代收集算法:

二、入门:从0到1带你一文读懂Java垃圾回收机制

深入探索Java垃圾回收机制:从入门到实战



在软件开发中,内存管理是关键环节。Java的垃圾回收机制就像守护者,自动回收不再使用的内存,确保系统稳定且高效。让我们一起走进Java的世界,了解这个幕后英雄的运作原理。



1.基础知识:垃圾回收的原理与作用
内存管理的核心任务在于垃圾回收,它自动避免内存泄漏和野指针问题。垃圾回收的最大优点是提升开发效率,确保系统性能。其工作流程包括识别不再使用的对象,并释放相应的内存,为新数据腾出空间。

2.对象生命周期的奥秘
从创建到消亡,每个Java对象都有其生命周期。从ObjectLifecycle类的示例中,我们可以看到对象从出生、活跃、变为不可达(引用失效),到最终被回收的过程。理解这些阶段对于深入理解垃圾回收至关重要。

3.判断策略大揭秘
-引用计数法:通过计数对象引用,简单但无法处理循环引用。而引用可达性分析则是关键,它从GCRoots(如栈帧、类静态属性等)出发,判定哪些对象还能被访问,从而确定生存状态。
-可达性分析:通过遍历GCRoots,判断对象是否存活,这种方法能有效处理循环引用,是JavaGC的主要策略。

4.实战演练:垃圾回收算法与实例
从引用计数问题到Java虚拟机的GCRoots,我们通过示例代码探索如何在实践中应用这些概念。理解强引用、软引用和虚引用,它们在回收过程中扮演的不同角色,是理解垃圾回收算法的基础,如标记-清除、复制和标记-整理。

标记-清除算法虽然解决了碎片问题,但移动对象可能带来开销。3.4分代收集策略则细致划分了新生代(如Serial、ParNew)和老年代(如CMS、ParallelOld),针对不同生命周期的对象进行优化。



5.垃圾回收器的多样性
Java的HotSpot虚拟机提供了丰富的垃圾回收器,如单线程的Serial和多线程的ParNew,以及并发且面向服务端的G1。每种回收器都有其适用场景,如吞吐量优先的ParallelScavenge和关注停顿时间的G1。

值得注意的是,G1收集器在大内存场景表现优异,尤其是JDK17的ZGC,其停顿时间显著减少,而CMS的并发老年代问题也有所改善,但内存占用和执行负载有所增加。



总结来说,选择合适的垃圾回收器,需要根据项目需求、内存大小和性能指标进行权衡。在实际开发中,理解全生命周期管理和内存管理策略,如FullGC触发条件,是避免性能瓶颈的关键。

三、JVM有哪些垃圾回收算法?

在JVM运行时数据区存在一个堆区,堆是一个巨大的对象池。在这个对象池中管理着数量巨大的对象实例,而池中对象的引用层次,有的是很深的。一个被频繁调用的接口,每秒生成对象的速度,是很大的,同时,对象之间的关系,形成了一张巨大的网。

发布人:nki25208857 发布时间:2024-08-01