04JVM-对象的死亡与对象引用

一、对象死了吗

垃圾收集器在回收Java对象时,首先要确定对象是否存活。在虚拟机规范中,定义了两种方式判断对象的是否被回收。

1. 引用计数法(Reference Counting)

给对象添加一个引用计数器,当有地方引用到它时,计数器加1;当引用失效时,计数器减1;只要当计数器为0时,该对象就不可能再被引用。

引用计数器法的实现比较简单,判断效率也很高,但是在主流的Java虚拟机里面没有选用来管理内存,其中最主要的原因是它很难解决对象之间相互循环的引用问题。

/**
 * Created by ZRD on 2017/02/14.
 * 测试引用计数法的对象回收现象
 */
public class ReferenceCountingGC {

    /**
     * VM Args: -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime
     * @param args
     */
    public static void main(String[] args) {
        testGC();
    }

    public Object instance = null;

    private static final int _1MB = 1 * 1024 * 1024; //1B*1024=1KB

    private byte[] bigSize = new byte[_1MB];

    public static void testGC() {

        ReferenceCountingGC objA = new ReferenceCountingGC();
        ReferenceCountingGC objB = new ReferenceCountingGC();

        objA.instance = objB;
        objB.instance = objA;

        // 假设在这里发生GC
        System.gc();
    }

}
2017-02-14T10:27:19.994+0800: [GC [PSYoungGen: 4669K->2712K(37888K)] 4669K->2712K(123904K), 0.0217407 secs] [Times: user=0.05 sys=0.00, real=0.02 secs] 
2017-02-14T10:27:20.016+0800: [Full GC [PSYoungGen: 2712K->0K(37888K)] [ParOldGen: 0K->2577K(86016K)] 2712K->2577K(123904K) [PSPermGen: 2931K->2930K(21504K)], 0.0123248 secs] [Times: user=0.08 sys=0.00, real=0.01 secs] 
2017-02-14T10:27:20.028+0800: Total time for which application threads were stopped: 0.0342405 seconds
Heap
 PSYoungGen      total 37888K, used 1638K [0x00000007d6000000, 0x00000007d8a00000, 0x0000000800000000)
  eden space 32768K, 5% used [0x00000007d6000000,0x00000007d6199ac8,0x00000007d8000000)
  from space 5120K, 0% used [0x00000007d8000000,0x00000007d8000000,0x00000007d8500000)
  to   space 5120K, 0% used [0x00000007d8500000,0x00000007d8500000,0x00000007d8a00000)
 ParOldGen       total 86016K, used 2577K [0x0000000782000000, 0x0000000787400000, 0x00000007d6000000)
  object space 86016K, 2% used [0x0000000782000000,0x0000000782284580,0x0000000787400000)
 PSPermGen       total 21504K, used 2961K [0x000000077ce00000, 0x000000077e300000, 0x0000000782000000)
  object space 21504K, 13% used [0x000000077ce00000,0x000000077d0e4608,0x000000077e300000)

4669K->2696K(37888K)上面的日志信息中可以获取到。说明这个时间段发生了垃圾回收,也就意味着虚拟机并没有因为这两个对象相互引用而没有回收,实际已经被回收了。

2. 可达性分析(Reachability Analysis)

可达性分析算法的思路是:以GC Roots为起点,从这些节点向下搜索,所有走过的路径称为引用链(Reference Chain);当一个对象没有GC Roots的对象引用它时,该对象就会成为垃圾收集器的目标

在Java语言中,GC Roots对象包括下面几种:
1. Java栈中引用的对象(也就是栈帧中的本地变量表)
2. 方法区中的类静态属性引用的对象
3. 方法区中的常量引用的对象
4. Native方法引用的对象

GC Roots

如上图,Object5,Object6,Object7会成为垃圾收集器的目标

二、reference引用

在Java中,有4中引用类型,用来定义引用的强弱。方便的内存不够时,逐步按等级定义回收的策略。

一些常见的缓存系统设计中比较常见

按引用的强弱程度分为4类

1. 强引用

强引用在代码中随处可见。类似ReferenceCountingGC objA = new ReferenceCountingGC();这种就是强引用。

只要强引用还存在,垃圾收集器永远不会回收。

2. 软引用(SoftReference)

  • 描述一些还有用,但非必须的对象。

在系统发生内存溢出之前,将会把这些对象列入回收范围进行第二次回收。

如果回收还没足够的内存,则会发生内存溢出异常

3. 弱引用(WeakReference)

  • 非必须的对象
  • 只能存活到下次垃圾收集之前

当垃圾收集器开始工作时,无论内存是否足够,都会回收掉这类对象

4. 虚引用(PhantomReference)

  • 幽灵引用或者幻影引用

一个对象是否有虚引用,完全不会对其生存时间构成影响,也无法通过虚引用来获取一个对象实例。

  • 设置该类引用的唯一目的是这个对象被垃圾收集器回收时能够收到一个系统通知

三、回收方法区

很多人认为方法区是没有垃圾收集的,Java虚拟机规范也说可以不要求在该区域实现垃圾收集,因为回收效果不好。

方法区的回收内容:废弃常量,无用的类

1. 回收废弃常量

回收废弃常量和回收Java堆中的对象非常相似,比如一个字符串,会放入常量池,当前系统中没有任何String对象引用常量池中的字符串,如果这个时候发生内存回收,系统会把字符串清理出常量池。

2. 回收无用的类

判断是否为无用的类有几个条件
* 该类的虽有对象均已被回收,也就是堆中不存在该类的任何对象
* 加载该类的ClassLoader已经被回收
* 该类对应的java.lang.Class对象没有任何地方被引用,也没有地方通过反射访问该类

对象的finalize()方法

当对象没有GC Roots引用链时,还没这么快被回收,对象会被第一次标记,并且还要做一个筛选判断有没有必要执行finalize(),筛选标准是对象没有重写finalize()或者已经被虚拟机调用过。

当判断有必要执行时,放入一个F-Queue队列中等待执行

如果在finalize()方法中将该对象重新产生一个GC Roots引用,则该对象成功逃过垃圾回收器的回收

但其实不鼓励这种做法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值