在java的垃圾回收中,jvm是如何判断堆中的对象是否已死呢?主流的判断方法有两种。
1.引用计数算法:
这种算法的思路是如果某一个对象被别的对象引用,那么就把他们引用计数器加上1,这样当进行垃圾回收时如何判断该引用的数量为0,此时就代表没有进行任何对象对其进行引用,这种方法判断效率很高,在很多情况下是个不错的选择,例如微软的COM,AS3的FlashPlayer,Python语言等都是采用引用计数器进行判断的,java没有采用此 用法的原因是他无法解决循环引用的问题。
eg :
public class RefernceCountGC{
public static instance = null;
public static final int _1MB = 1024 * 1024 ;
private byte[] bigSize = new byte[2 * _1MB];
public static void testGC(){
RefernceCountGC objA = new RefernceCountGC();
RefernceCountGC objB = new RefernceCountGC();
objA.instance= objB ;
objB.instance = objA ;
objA = null;
objB = null ;
System.gc();
}
}
上面的两个对象objA和objB相互引用,如果用计算器算法的话会导致无法进行回收。
2.根搜索算法:
主流的语言Java,C#甚至古老的语言Lisp都是采用根搜索算法进行垃圾回收的,这个算法的思路就是通过命名一系列的“GC Root"作为起点,从这些起点开始向下搜索,这样可以形成一条引用链,该引用链之外的对象都将被回收,在java钟只有一下的对象才可以被作为GC Root.
1>虚拟机栈(栈帧中的本地方法表)中引用的对象。
2>方法区中类静态属性引用的对象。
3>方法区中常量引用的对象。
4>本地方法栈JNI(即一般说的Native方法)的引用对象。
3.关于引用:
在jdk1.2之前,java中的引用时这样定义的:如果reference类型的数据中存储的是另一块内存的起始地址,就称这块内存代表着一个引用。这样定义过于狭隘,因为这是一个对象只有引用和被引用两种状态,描述一下"食之无味,弃之可惜"的对象则无能无力,我们希望描述这样的一类对象,当内存空间还够是,则能留在内存中,否则内存进行垃圾回收后还紧张,那么可以抛弃这些对象,jdk1.2后对引用进行了扩充,分为:强引用(Strong Reference),软引用(Soft Reference),弱引用(Weak Reference),虚引用(Phantom Reference)四种。
3.1 强引用。
该引用是代码中普通存在的,例如Object objA = new Object(),只要强引用存在,垃圾收集器永远不会回收掉被引用的对象。
3.2 软引用。
该引用用来描述一些还有用,但是并非必须得对象,在系统将要爆发内存溢出之前,将会把这些对象列在进行回收的范围之内,进行二次回收后如果还是内存不足,这时候才跑出内存溢出的错误。
3.3 若引用。
该引用也是用来描述非必须对象的,强度比软引用更弱被若引用引用的对象只能存活到下一次垃圾回收之前。
3.4 虚引用也称为幻影引用。
是最弱的一种的引用,一个对象是否存活与其生存周期没有什么影响,设置该引用的目的仅仅 是希望这个对象被释放的时候能够收到一个系统通知。
4.生存还是死亡?
如果进行垃圾回收的时候发现一个对象没有在GC Root链上,那么就需要进行两次的标记过程,如果当前发现没有关联在GC Root链上,那么就会进行第一次标记,如果此时对象的finalize()方法没有被覆盖或该方法已经被虚拟机调用过,那么此时将被标记为没有必要执行,此时该对象会被放入”即将回收“集合,否则就会放入F-Queue的对象中等待执行finalize()方法,如果在此方法中对象将自己与GC Root链上的任何一个对象关联,那么就会被溢出”即将回收“集合。
分享到:
相关推荐
【JVM的GC如何判断对象是否死亡】 在Java的虚拟机(JVM)中,垃圾收集(GC)机制是自动管理内存的关键部分。它负责识别并清除那些不再使用的对象,以便释放内存资源。理解GC如何判断对象是否死亡是优化Java应用程序...
本文将详细讲解JVM如何判断对象已死的两种主要算法:引用计数算法和可达性分析算法,以及JDK 1.2之后引入的不同类型的引用。 首先,我们来看引用计数算法。这是一种简单的对象存活判断方法,为每个对象添加一个引用...
在Java虚拟机(JVM)中,对象的生命周期包含了多个阶段,这些阶段共同决定了一个对象从诞生到消亡的过程。以下是这些阶段的详细介绍: **创建阶段(Creation)** 在这个阶段,对象从无到有,主要经历以下几个步骤:...
面向对象是一种编程范式,它使用“对象”来设计软件。...开发者在编写Java代码时,需要理解这些基本概念,并能够合理地使用面向对象的特性以及管理JVM内存模型,以编写出高质量、高效率的Java应用程序。
java对象在jvm中的存储情况 jvm
Jvm 对象内存分配理解 Jvm 对象内存分配是 Java 虚拟机(Jvm)中的一种机制,用于在堆中分配对象的内存空间。该机制涉及到类加载检查、内存分配、对象初始化等多个步骤。 类加载检查 在 Jvm 对象内存分配中,首先...
原项目下载地址:...使用说明: 1、将SizeOf.jar放到Eclipse工程路径下,添加到classpath中; 2、运行前添加VM参数:-javaagent:lib/SizeOf.jar 运行即可(将jar放在lib路径下)。
这种情况可能是由于数据量过大、死循环、静态变量和静态方法过多、递归、无法确定是否被引用的对象等原因引起的。同时,虚拟机不回收内存(内存泄漏)也可能导致内存溢出。 解决内存溢出的方法有两种:一是优化程序...
Java基础知识学习:包括JVM虚拟机、对象模型等Java基础知识代码案例Java基础知识学习:包括JVM虚拟机、对象模型等Java基础知识代码案例Java基础知识学习:包括JVM虚拟机、对象模型等Java基础知识代码案例Java基础...
介绍了heap dump和thread dump,以及详细介绍dump工具Memory Analyzer的使用,最后讲解了Java对象的内存布局。
- 可达性分析算法:这种方法通过确定对象的引用链来判断对象是否可达。GC根对象包括虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中native方法引用的对象。如果一个对象...
5. 内存管理:JVM的垃圾回收机制自动管理内存,包括对象的分配和回收。常见的垃圾收集算法有标记-清除、复制、标记-整理和分代收集等。 6. 多线程:JVM支持多线程并发执行,每个线程都有自己的程序计数器和虚拟机栈...
相反,JVM 将堆划分为不同的区域(如新生代和老年代),并根据对象的存活时间来进行有针对性的垃圾回收。 ##### 2.5 JVM 的本地接口 JVM 的本地接口(JNI)允许 Java 程序直接调用本地方法(通常是 C 或 C++ 编写...
堆内存主要用于存放对象实例。新生代(Young Generation)包括Eden区和两个Survivor区(From和To),采用复制算法进行垃圾回收。老年代(Tenured Generation)使用标记-整理或标记-压缩算法。垃圾回收器有Serial、...
JVM夺命连环问 JVM 讲讲JVM的10种垃圾回收器? 什么是垃圾回收中的STW? 什么是可达性分析算法? 讲一讲JVM中的垃圾回收算法? 讲一讲JVM中的分代模型 讲一讲CMS垃圾回收器 讲一讲G1垃圾回收器 JVM的运行时数据区有...
- **内存回收**:通过可达性分析算法判断对象是否存活,如引用计数法和根可达法。 finalize()方法用于对象在被回收前的自定义清理逻辑,但不应依赖它进行资源释放。 3. **类加载机制** - **类加载过程**:包括...
在这个压缩包中,"JVM图解.png"可能是对JVM内部结构的可视化表示,"JVM图解"可能是一个详细的文档,解释了JVM的工作原理,而"JVM指令手册 中文版"则提供了JVM可执行的所有指令的详细信息。下面,我们将深入探讨JVM的...
总结,Java性能调优中,理解JVM对象创建和内存分配机制是关键。通过合理的设计、优化策略以及JVM参数配置,可以显著提升应用的运行效率和内存管理效果。在实际工作中,应结合监控工具(如VisualVM、JProfiler等)...