`

Java垃圾收集之对象引用

 
阅读更多

引用计算方法

        Java中没有采用引用计数方法管理内存,最主要的原因是此方法很难解决对象间的循环引用问题。

 

        Java中采用的引用管理方法为:根搜索算法。基本思路是通过一系列的名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,所走过的路径称为“引用链(Reference Chain)”。当一个对象与其GC Roots之间没有任何通路的时候,就判定此对象可以被回收。

 

再谈引用

        Java1.2之前对引用的定义是:如果reference类型的数据中存储的数值代表的是另一块内存的起始地址,就称这块内存代表着一个引用。在1.2之后,Java将引用的概念进行了扩充,分为以下4种类型:

 

  • 强引用(Strong Reference)

        指一个引用直接指向一个对象,类似于 Object o = new Object(),只要强引用存在,GC就不可能将它回收。

 

  • 软引用(Soft Reference)

        用来描述一些还有用的,但并非必须的对象。对于软引用对象,系统在将要发生内存溢出异常之前,会将其列为回收对象并进行第二次回收。如果这次回收之后还是没有足够的内存,才会抛出内存溢出异常。Java中提供SoftReference类实现软引用。

 

  • 弱引用(Weak Reference)

        同样用来描述非必须对象,但强度比软引用更弱,被弱引用关联的对象只能生存到下一次垃圾回收发生之前。当GC工作时,不论内存是否充足,弱引用对象都会被列在回收范围内。 Java提供了WeakReference类实现弱引用。

 

  • 虚引用(Phantom Reference)

        也称为幽灵引用或者幻影引用,是最弱的一种引用类型。虚引用存在与否,都不会对一个对象的生存时间产生任何影响,也无法使用虚引用来获取对象实例。设置虚引用的唯一目的就是希望在此对象在垃圾回收的时候收到一个系统通知。Java提供了PhantomReference类实现虚引用。

 

对象的生存还是死亡

在根搜索算法中不可到达的对象,也不一定就是“非死不可”的对象,要真正的回收一个对象,至少要经历两次标记:如果在对对象进行根搜索之后没有发现有与对应的GC Roots相连的引用链,那么它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”。

当对象被判定为“有必要执行finalize()方法”,那么这个对象会被放置在一个名为“F-Queue”的队列之中,并在稍后又一条由虚拟机自动建立、低优先级的Finalizer线程去执行每个对象的finalize()方法,但不保证一定会等待每个对象的finalize方法执行结束,因为如果有对象的finalize方法很耗时或者干脆就是死循环,那么整个F-Queue中的对象都会处于等待状态甚至虚拟机崩溃。

finalize()方法是对象逃脱被回收的最后一次机会,GC会对F-Queue中的对象进行第二次小规模标记,如果对象想要逃脱被回收的命运,只要在finalize()方法中与引用链上的任何一个对象建立关联即可。

注意,任何对象的finalize()方法只会被执行一次。

 

不建议复写finalize()方法来进行类似资源回收的行为,使用try-finally或者其他方式都可以做的更好更及时。

分享到:
评论

相关推荐

    JAVA垃圾回收机制

    垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变。垃圾收集的目的在于清除不再...

    详细介绍Java垃圾回收机制

    垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变。垃圾收集的目的在于清除不再...

    Java理论与实践:JVM 1.4.1中的垃圾收集

    并简单概述了老对象和年轻对象、分代收集、小的收集、代间引用、跟踪代间引用、卡片标记、JDK 1.4.1 默认收集器、并行收集器和并发收集器、微调垃圾收集器等理论或技术。得出:随着JVM的发展,默认垃圾收集器变得...

    java虚拟机学习笔记之垃圾收集

    垃圾收集是自动释放不在被程序使用的对象的过程。为了能够无限制的使用内存,大部分的java虚拟机都附带有垃圾收集堆。  ★为什么使用使用垃圾收集  垃圾收集,也是把程序中不需要的对象作为“垃圾”进行回收,...

    谈谈你对垃圾回收机制的了解?.docx

    引用计数算法:就是为对象添加一个引用计数,用于计数对象被引用的情况,如果计数为0,表示 对象可以被回收.(java并没有选择引用计数,因为存在一个基本难题,就是很难处理循环引用关系) 可达性分析:这种类型的垃圾收集...

    Java对象的强、软、弱和虚引用1

    3.2 如果使用软引用SoftReference的特点是它的一个实例保存对一个Java对象的软引用,该软引用的存在不妨碍垃圾收集线程对该Java对象的回收 3.

    JVM入门实战/arthas实战/垃圾回收算法/垃圾回收器/jvm内存模型分析

    第三节:定位垃圾对象的依据 1.1 引用计数法 1.2 可达性算法 第四节:垃圾回收算法 1.1标记清除算法 1.2复制算法 1.3 标记整理(标记压缩)算法 第五节:垃圾回收器 1.1Serial/Serial Old收集器 1.2 ParNew收集...

    Java理论与实践:用弱引用堵住内存泄漏

    当垃圾收集器跟踪堆的时候,如果对一个对象的引用只有弱引用,那么这个referent就会成为垃圾收集的候选对象,就像没有任何剩余的引用一样,而且所有剩余的弱引用都被清除。弱引用对于构造弱集合最有用。弱引用和弱...

    Java理论与实践:它是谁的对象?

    对于每个动态对象,必须要么实现引用计数以模拟 垃圾收集效果,要么管理每个对象的“所有权”--确定哪个类负责删除一个对象。通常,对这种所有权的维护并没有什么成文的规则,而是按照约定(通常是不成文的)进行...

    一些常见的Java面试题.docx

    当对象没有任何引用指向它们时,它们将被视为垃圾,然后由Java的垃圾收集器自动删除。 强类型:Java是强类型的编程语言,这意味着每个变量都必须先声明其数据类型。 安全性:Java设计时的重点之一是安全性,因此它...

    Java是一种广泛使用的编程语言

    当对象没有任何引用指向它们时,它们将被视为垃圾,然后由Java的垃圾收集器自动删除。 强类型:Java是强类型的编程语言,这意味着每个变量都必须先声明其数据类型。 安全性:Java设计时的重点之一是安全性,因此它...

    Java实时应用程序中的内存管理

    通常,Java运行时会遍历堆,检查不再被其他对象引用、从而可以安全删除的对象,然而,由于垃圾收集占用CPU周期,所以它可能会影响应用程序代码的执行。实时应用程序有严格的时间要求,即它们必须在确定的、已知的...

    Java中对象的销毁

    Java中的基本数据类型变量和对象的名称...  Java中垃圾收集器自动地定期扫描Java对象的动态内存,并将所有的引用对象加上标记,在对象运行结束后(无引用变量对该对象进行关联),清除其标记,并将所有无标记的对象作

    深入Java虚拟机(原书第2版).pdf【附光盘内容】

    第5-20章深入描述了java技术的内部细节,包括垃圾收集、java安全模型、java的连接模型和动态扩展机制、class文件、运算及流程控制等等,其中等6章和附录a-c完全可以作为class文件和指令含集的参考手册。本书还附带...

    java面向对象程序设计.pptx

    教学目标 理解数据抽象和数据隐藏 创建类 能够创建和使用对象 能够控制对实例变量和方法的访问 方法的重载 构造函数的使用 理解this引用的用法 理解Java的垃圾收集机制 static方法和域的使用 类的组合 包的创建和...

    Java后端面试问题整理.docx

    • 熟悉JVM内存区域,常用引用类型,垃圾回收机制、算法以及常见的GC垃圾收集器(Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1) • 熟悉常用IO模型(BIO、NIO、AIO),熟悉JVM类加载过程与...

    java 模拟 面试题 答案

    Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object类中定义的,因此所有的类都继承了它。...

    Java实时性及嵌入式实时Java处理器研究

    由于嵌入式系统多数为实时系统,传统Java技术应用于嵌入式系统的主要不足之处表现为:由于Java虚拟机是在运行中对引用到的类进行动态装载、解析和连接,影响了系统的实时性;垃圾收集器(GC)的自动运行导致了任务...

    21天学会java开发网络游戏

    这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾...

    Java面试题及答案(面试题集锦)

    Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承...

Global site tag (gtag.js) - Google Analytics