JVM中判断对象是否需要回收的方法

简介: JVM中判断对象是否需要回收的方法



       在堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“ 存活 着,哪些已经 死去 ”。

引用计数算法


       引用计数法是一种内存管理技术,它是通过对每个对象进行引用计数来判断对象是否可以被释放的。

基本思想

       每一个对象都有一个计数器,当有一个新的指针指向该对象时,该对象的计数器增加1;当有一个指针不再指向该对象时,该对象的计数器减少1。当对象的计数器为0时,说明该对象没有被任何指针引用,即该对象已经没有被使用,可以被释放。

引用计数法的优点

       实现简单、实时性高。它可以较快地释放不再使用的对象,因为只需要在对象引用数为0时立即释放该对象,不需要等待垃圾回收器运行。

引用计数法的缺点

一个常见的问题是循环引用,即两个或多个对象相互引用,导致它们的引用计数器永远不会为0,这样就会导致内存泄漏。解决循环引用问题需要引入其他的垃圾回收算法,比如标记-清除、复制和标记-整理等算法。同时,引用计数还可能会对程序的性能产生一定的影响,因为需要维护每个对象的引用计数器,这会增加程序的开销。

可达性分析算法


       可达性分析算法是现代垃圾回收器常用的算法之一。其基本思想是通过一系列扫描操作,检查每个对象与根对象之间是否存在引用链,如果不存在引用链,则说明该对象已经没有被使用,可以被释放。

       在可达性分析算法中,根对象是指一些已知的存在于内存中的对象,如全局变量、静态变量和栈中的变量等。垃圾回收器通过对根对象的扫描,检查每个根对象是否引用了其他对象,如果引用了,则对被引用的对象进行标记。然后对所有被标记的对象再进行扫描,检查它们是否引用了其他对象,如果引用了,则对被引用的对象进行标记。依此类推,直到所有可到达对象都被标记为活动对象,未被标记的对象则可以被视为垃圾对象,可以进行回收。

可达性分析算法的优点

       可达性分析算法能够精确地确定哪些对象可以被回收。同时,该算法具有较好的扩展性,可以应用于分代垃圾回收、增量垃圾回收、并行垃圾回收等多种垃圾回收方案。

可达性分析算法的缺点

       首先,该算法需要对所有对象进行扫描,因此时间复杂度较高,可能会影响程序的性能。其次,该算法无法处理循环引用的情况,即当两个或多个对象相互引用时,无法确定它们是否应该被回收。因此,可达性分析算法需要与其他垃圾回收算法配合使用,如引用计数法、标记-清除、复制和标记-整理等算法,以便实现更高效的垃圾回收。

可达性分析算法的工作流程

初始标记阶段

       在这个阶段,JVM会暂停所有的应用线程,进行一次快速的标记。这个阶段的目标是标记GC Roots直接关联的对象,速度较快。

并发标记阶段

       在这个阶段,垃圾回收器与应用线程同时运行,标记所有的可达对象。由于与应用线程并发执行,这个阶段的时间相对较长。

重新标记阶段

       在并发标记阶段完成后,为了处理在标记阶段应用线程继续运行而产生的新的引用关系,需要进行一次短暂的重新标记。这个阶段同样需要停顿应用线程。

并发清除阶段

       最后一个阶段是并发清除阶段,垃圾回收器清理掉那些不再被引用的对象,并释放它们占用的内存。

总结

       综合考虑,两者结合使用能够弥补各自的不足。引用计数法处理实时性要求高的场景,而可达性分析算法则提供更精确的回收判断。在实际应用中,选择适当的内存管理技术取决于具体的场景和需求。这种综合运用有助于充分利用它们的优势,提高系统的性能和稳定性。

相关文章
|
1月前
|
存储 算法 Java
散列表的数据结构以及对象在JVM堆中的存储过程
本文介绍了散列表的基本概念及其在JVM中的应用,详细讲解了散列表的结构、对象存储过程、Hashtable的扩容机制及与HashMap的区别。通过实例和图解,帮助读者理解散列表的工作原理和优化策略。
37 1
散列表的数据结构以及对象在JVM堆中的存储过程
|
2月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
73 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
2月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
58 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
2月前
|
算法 Java
JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
本文详细介绍了JVM中的GC算法,包括年轻代的复制算法和老年代的标记-整理算法。复制算法适用于年轻代,因其高效且能避免内存碎片;标记-整理算法则用于老年代,虽然效率较低,但能有效解决内存碎片问题。文章还解释了这两种算法的具体过程及其优缺点,并简要提及了其他GC算法。
 JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
|
2月前
|
存储 算法 Java
【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
60 2
|
2月前
|
Java
JVM进阶调优系列(5)CMS回收器通俗演义一文讲透FullGC
本文介绍了JVM中CMS垃圾回收器对Full GC的优化,包括Stop the world的影响、Full GC触发条件、GC过程的四个阶段(初始标记、并发标记、重新标记、并发清理)及并发清理期间的Concurrent mode failure处理,并简述了GC roots的概念及其在GC中的作用。
|
2月前
|
算法 Java
JVM进阶调优系列(3)堆内存的对象什么时候被回收?
堆对象的生命周期是咋样的?什么时候被回收,回收前又如何流转?具体又是被如何回收?今天重点讲对象GC,看完这篇就全都明白了。
|
4月前
|
存储 Java 程序员
Java中对象几种类型的内存分配(JVM对象储存机制)
Java中对象几种类型的内存分配(JVM对象储存机制)
89 5
Java中对象几种类型的内存分配(JVM对象储存机制)
|
4月前
|
缓存 监控 算法
吃透 JVM 诊断方法与工具使用
【8月更文挑战第4天】深入了解并掌握JVM诊断需把握几大要点:1) 熟悉JVM内存模型,如堆、栈及方法区;2) 掌握垃圾回收机制与算法;3) 运用工具如`jps`(查看Java进程)、`jstat`(监控运行状态)、`jmap`(生成堆快照)、`jhat`(分析堆快照)、`jstack`(检查线程栈); 4) 利用专业工具如Eclipse Memory Analyzer分析堆转储文件查找内存泄漏; 5) 动态监控与调整JVM参数; 6) 结合日志分析性能瓶颈。通过实战案例加深理解,有效应对JVM性能问题。
|
2月前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
39 4