JVM—对象已死?
创始人
2024-11-16 02:38:22
0

 参考资料:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)周志明

在堆里面存放着 Java 世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”。

1、如何判断对象存活

1.1 引用计数法

  • 给对象增加一个引用计数器,当对象被引用一次计数器加一、当引用失效时计数器减一

  • 任何时候计数器为0的对象就不可能再被使用

这个方法虽然占用一定内存但是原理简单、效率也很高,大多情况都是不错的算法。但Java虚拟机并没有使用这个方法因为这个方法还要考虑很多额外的情况,配合大量处理逻辑才能解决问题。

引用计数法的缺点:

public class ReferenceCountingtGC {          public Object instance = null;          public static final int _1MB = 1024 * 1024;          //这个成员属性的唯一意义就是占点内存,以便在GC日志中看清楚是否回收过     private byte[] bigSize = new byte[2 * _1MB];          public static void testGC(){         ReferenceCountingtGC objA = new ReferenceCountingtGC();         ReferenceCountingtGC objB = new ReferenceCountingtGC();         objA.instance = objB;         objB.instance = objA;                  //假设在这发生GC,objA和objB能否被回收?         System.gc();     } } 
  • 这两个对象objA和objB已经不可能再被访问了,但是它们因为互相引用对方,导致它们的引用计数都不为零。 所以引用计数算法就无法回收他们

1.2 可达性分析算法

  • 这个算法的基本思路就是通过一系列称为“GC Roots”的根对象作为起始节点集。

  • 从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”。

  • 如果某个对象到GC Roots直接没有引用链就代表这个对象不能被使用。

可作为java中Gc Roots的对象包含哪些?

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

  2. 方法区中的静态属性引用对象。(例如被Static修饰的字符串)

  3. 方法区中常量引用的对象。(例如字符串常量池的引用)

  4. 在本地方法栈中 JNI(即通常所说的 Native 方法)引用的对象。

  5. java虚拟机内部的引用。(例如数据类型对应的Class对象,一些常驻对象(OOM),系统类加载器)

  6. 所有被同步锁(synchronized 关键字)持有的对象。

  7. 反映 Java 虚拟机内部情况的 JMXBean、JVMTI 中注册的回调、本地代码缓存等。

2、再谈引用

无论是引用计数法还是可达性分析算法,判断对象是否存活都和对象的引用分不开。

在jdk1.2以后对引用进行了扩充,将引用分为:

  1. 强引用

  2. 软引用

  3. 弱引用

  4. 虚引用

这四种引用强度依次递减。

2.1 强引用

强引用是最常见的引用类型,是程序代码之间普遍存在的引用赋值,例如这样的引用关系,在任何情况下只要强引用还在JVM就不会回收被引用的对象。

Object obj = new Object();

2.2 软引用

软引用是用来描述一些还有用但非必需的对象。在系统将要发生内存溢出异常之前,这类对象会被列为可回收的资源。在jdk1.2后提供了SoftReference类来实现软引用。

Object obj = new Object(); SoftReference softReference = new SoftReference<>(obj); 

内存不足时,GC会回收软引用指向的对象,以释放空间,避免OutOfMemoryError

2.3 弱引用

弱引用也用来描述非必需对象,但是其强度比软引用更弱,只能生存到下一次垃圾回收发生之前。使用WeakReference类来实现弱引用。

Object obj = new Object(); WeakReference weakReference = new WeakReference<>(obj); 

GC工作时,无论内存是否足够,都会回收被弱引用关联的对象。

2.4 虚引用

虚引用是最弱的一种引用关系。无法通过虚引用来取得一个对象实例,设置虚引用关联的唯一目的是在这个对象被收集器回收时收到一个系统通知。虚引用PhantomReference必须和引用队列(ReferenceQueue)联合使用。

ReferenceQueue queue = new ReferenceQueue<>();        Object object = new Object();        PhantomReference phantomReference = new PhantomReference<>(object, queue); 

3、生存还是死亡

真正宣告一个对象的死亡需要至少经历两次标记的过程

1、如果对象进行可达性分析后没有与GC Roots相连的引用链,那么就会被第一次标记

  • 接下来将会执行一次筛选,筛选条件是对象是否有必要执行finalize()方法。(假如对象没有覆盖finalize方法或者finalize方法已经被调用过。虚拟机都会将这两种情况视为没必要执行)

  • 如果这个对象被判断为有必要执行finalize方法,那么对象将会被放在一个F-Queue队列中。并在稍后由一条虚拟机自动建立的、低调度优先级的Finalize线程去执行它们的Finalize()方法。

2、finalize方法是对象逃脱死亡的最后机会,收集器将会对F-Queue中的对象进行第二次小规模的标记。

  • 如果对象要拯救自己,那么需要重新与引用链上的任何一个对象建立关联即可。

  • 这种自救的机会只有一次,因为一个对象的 finalize()方法最多只会被系统自动调用一次

4、回收方法区

  • 方法区回收的性价比较低

  • 方法区主要回收两部分内容:废弃的常量和不再使用的类型。

1、回收废弃常量的条件

  • 已经没有任何字符串对象引用常量池的“Java”常量,并且虚拟机中也没有其他地方引用这个字面量。

2、不使用类型的回收条件

  • 该类的所有实例都被回收了,也就是Java堆中不存在该类及其任何派生子类

  • 加载该类的类加载器已经被回收

  • 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

相关内容

热门资讯

正版授权!金花房卡批发价神牛大... 神牛大厅是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:【3329006910】或QQ:332900...
正规平台有哪些,金花充值房卡江... 正规平台有哪些,金花充值房卡江山大厅/微信链接房卡充值链接Sa9Ix苹果iPhone 17手机即将进...
IA解析/金花房卡专卖店天龙大... 天龙大厅房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 3、根...
科技实测!微信金花房卡怎么弄南... 南瓜大厅/新道游是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:【3329006910】或QQ:33...
推荐一款!金花房卡是正规的新天... 推荐一款!金花房卡是正规的新天王/老夫子大厅/房卡价格表多少钱一张Sa9Ix苹果iPhone 17手...
正版授权!怎么买斗牛房卡起点大... 今 日消息,起点大厅房卡添加微信33549083 苹果今日发布了 iOS 16.1 正式版更新,简单...
正规平台有哪些,斗牛房卡充值九... 正规平台有哪些,斗牛房卡充值九天大厅/微信链接房间卡怎么购买九天大厅是一款非常受欢迎的游戏,咨询房/...
IA解析/怎么买斗牛房卡新九天... 微信游戏中心:新九天大厅房卡在哪里买打开微信,添加客服微信【88355042】,进入游戏中心或相关小...
终于找到“金花房卡一手货源/新... 新永和是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:160470940许多玩家在游戏中会购买房卡来...
ia实测“微信炸金花房间怎么创... 新众亿金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:15984933许多玩家在游戏中会购买房卡...
金花房卡购买正规渠道/微信链接... 金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:15984933许多玩家在游戏中会购买房卡来享受...
微信炸金花链接怎样弄/金花链接... 微信炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:160470940许多玩家在游戏中会购买房...
牛牛链接房卡那里有/微信房卡斗... 斗牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:160470940许多玩家在游戏中会购买房卡来享...
怎样购买微信金花房卡/微信牛牛... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:160470940许多玩家在游戏中会购买房卡来享...
微信牛牛链接金花房卡/微信链接... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:15984933许多玩家在游戏中会购买房卡来享受...
给大家讲解“购买斗牛金花房卡联... 悟空大厅是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:44346008许多玩家在游戏中会购买房卡来...
哪里有卖微信炸金花房卡/微信牛... 微信炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:160470940许多玩家在游戏中会购买房...
金花房卡从哪里购买/炸金花房卡... 金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:44346008许多玩家在游戏中会购买房卡来享受...
软件炸金花模式创建开房卡/微信... 金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:44346008许多玩家在游戏中会购买房卡来享受...
终于找到“购买金花房卡联系方式... 新八戒是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:15984933许多玩家在游戏中会购买房卡来享...