JVM_对象已死

垃圾收集器再对堆进行回收前,第一个要做的事就是确定对象是否还存活,判断方法有2种

1)引用计数法

2)可达性分析

1.引用计数法

给对象中添加一个引用计数器,每当一个地方引用这个对象时,计数器值+1;当引用失效时,计数器值-1。任何时刻计数值为0的对象就是不可能再被使用的。

缺点:

很难解决对象之间的相互循环引用问题,导致它们的引用计数都不为0,于是引用计数算法无法通知GC收集器收集它们。

2.可达性分析

通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的。

GC Roots对象:

(1). 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。

(2). 方法区中的类静态属性引用的对象。static对象

(3). 方法区中常量引用的对象。final对象

(4). 本地方法栈中JNI(Native方法)引用的对象。

扩展:引用

(1) 强引用 :只要强引用还存在,【垃圾收集器就永远不会回收该对象】

Object obj = new Object();

(2) 软引用 :软引用关联的对象,在系统发生内存溢出异常前,会将这些对象进行第二次回收。如果第二次回收还没有足够内存才抛出内存溢出异常。【内存空间足够,回收器就不会回收它,内存不足就会回收】

(3) 弱引用:描述非必需对象。关联的对象只能生存到下一次垃圾回收前,当垃圾收集器工作时,【无论当前内存是否足够,都会回收掉它们】。

(4) 虚引用 :无法通过虚引用来取得一个对象实例。唯一目的是能在这个对象被收集器回收时收到一个系统通知。【任何时候都可能被回收】

死亡过程

可达性分析没有发现与GCRoots的引用链

1.如果不可达,则标记筛选(条件是对象是否有必要执行finalize)
1)没必要,对象没有覆盖finalize方法或者finalize已经被虚拟机调用
2)有必要。放置在F-Queue队列中。这时候二次标记。如果重新与对象建立连接则不会被回收。

方法区的回收

永久代的垃圾收集主要回收两部分内容:废弃常量和无用的类

1.废弃常量
没有在其他地方引用则回收
2.无用的类
(1) 类的实例已被回收
(2) 加载该类的classloader已被回收
(3) 该类对应的class没有被引用,也无反射访问。

文章目录
  1. 1. 1.引用计数法
    1. 1.0.1. 缺点:
  • 2. 2.可达性分析
    1. 2.0.1. GC Roots对象:
  • 2.1. 扩展:引用
  • 2.2. 死亡过程
  • 2.3. 方法区的回收
  • | 139.6k