ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JVM如何知道一个对象该回收了呢?

2022-07-17 11:32:25  阅读:158  来源: 互联网

标签:finalize 对象 回收 GC 引用 JVM 方法


转自:

http://www.java265.com/JavaCourse/202204/2841.html

下文笔者讲述JVM虚拟机如何界定对象可以被回收的方法分享,如下所示:

回收就是通常我们所说的GC,那么何时我们才知道对象该回收呢
下文将一一道来,如下所示
 我们都知道在java中 程序计数器、虚拟机栈、本地方法栈这三个区域随线程而生,随线程而灭
   栈中的栈帧随着方法的调用和退出而进行着入栈和出栈的过程。
  每个栈帧分配多少内存在类结构确定下来时就已知的,方法结束或线程结束内存自然跟着回收了
 但是java中有一个地方堆,用于存储对象,这一部分区域不会自动消失,她需要JVM的垃圾回收器对其进行回收
 那么垃圾回收器如何界定垃圾呢?下文笔者将一一道来,如下所示

引用计数算法

给对象添加一个引用计数器
每当一个地方引用它时候
计数器就加1,当引用失效计数器就减1
任何时刻计数器为0的对象就是不可能再被使用了
这种方法实现简单,效率高,但是它很难解决对象的循环引用问题:
public class Test {

    private static final int a = 1024 *1024;
    private Object instance = null;
    public static void testGC(){
        Test objectA = new Test();
        Test objectB = new Test();

        objectA.instance = objectB;
        objectB.instance = objectA;

        objectA = null;
        objectB = null;
        // 假如这里发生GC,objectA和objectB会不会被回收
    }
}

可达性分析算法

这个算法的基本思路是通过一系列称为“GC Roots”(一组必须活跃的引用)作为起始点
从这些节点开始向下搜索,搜索走过的路径称为引用链
当一个对象到GC Roots没有任何引用链时候,那么证明此对象是不可用的。

在Java语言中,做作为GC Roots的对象包括以下几种:
1)虚拟机栈(栈帧中的本地变量表)中引用的对象。
2)方法区中类静态属性引用的对象。
3)方法区中常量引用的对象。
4)本地方法栈JNI(即一般说的Native方法)引用的对象。

引用

无论是通过引用计数器算法判断对象的引用数量,还是通过可达性分析算法判断对象引用链是否可达,判断对象是否可活都离不开引用
Java中将引用分为四种:
1.强引用(Strong Reference)
  是指程序代码中普遍存在的,类似“Object obj = new Object()”这类的引用,只有强引用还存在对象就不会被回收。

2.软引用(Soft Reference)
  软引用是用来描述一些还有用但是非必须的对象。对于软引用关联的对象,在系统将于发生内存溢出异常之前,将会把这些对象列进回收范围中进行二次回收。

3.弱引用(Weak Reference)
   也是用来描述非必须对象的,强度比软引用还弱一些,被软引用关联的对象只能存活到下一次内存回收之前。

4.虚引用(Phantom Referenece)
  也成为幽灵引用和幻影引用,为一个对象设置虚引用关联的唯一目的就是能在这个对象被回收时收到一个系统通知。

生存还是死亡

即使在可达性分析算法中不可达的对象,也并非一定是“非死不可”的,这时候他们暂时处于“缓刑”阶段,真正宣告一个对象死亡至少要经历两个阶段:

1.如果对象在可达性分析算法中不可达,那么它会被第一次标记并进行一次刷选,刷选的条件是是否需要执行finalize()方法
(当对象没有覆盖finalize()或者finalize()方法已经执行过了(对象的此方法只会执行一次)),虚拟机将这两种情况都会视为没有必要执行)
2.如果这个对象有必要执行finalize()方法会将其放入F-Queue队列中,稍后GC将对F-Queue队列进行第二次标记
如果在重写finalize()方法中将对象自己赋值给某个类变量或者对象的成员变量,那么第二次标记时候就会将它移出“即将回收”的集合
finalize()能做的工作,使用try-finally或者其他方式都能做到更好,更及时,所以不建议使用此方法。

方法区回收

永久代中回收的内容主要是两部分:废弃的常量和无用的类。判断无用的类(类卸载)必须满足三个条件:
1.该类所以的实例都已经被回收
2.加载该类的ClassLoader被回收
3.该类对应的java.lang.Class对象没有在任何地方引用,无法在任何地方通过反射访问该类的方法

标签:finalize,对象,回收,GC,引用,JVM,方法
来源: https://www.cnblogs.com/java265/p/16485856.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有