java判断一个对象是否存活

本文深入探讨Java中对象存活状态的判断方法,包括已弃用的引用计数法及主流的引用链法(可达性分析法)。通过详细解析两次标记筛选过程,帮助读者理解对象如何被垃圾回收机制判定为死亡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

众所周知,在java中一个对象如果死掉很快就会被垃圾回收机制处理了,但是怎么判断一个对象是否存活呢,这次就来记录学习一下

方法

主要有两个方法

1.引用计数法(已弃用)

原理:给java对象添加一个引用计数器,当被引用一次+1,引用失效-1,当计数器为0时则判定该对象死亡

缺点:遇见两个对象相互引用的情况则失效

2.引用链法(可达性分析法)

步骤:

<1.可达性分析

<2.第一次标记 & 筛选

<3.第二次标记 & 筛选

详解:

<1.可达性分析

找寻一个可以作为GC root的对象作为起点,从该起点向下搜索,当该对象没有任何引用链相连时,则判定该对象不可达

可以作为GC root的有:虚拟机栈中的对象、本地方法栈的jni对象、方法区的静态成员

不可达仅判定该对象不可达,还不能判定该对象是否失效

<2.第一次标记 & 筛选

当判定一个对象为不可达时,会将该对象放在即将回收的集合中,然后进行第一次标记筛选

筛选:如果该对象没有finalize()方法或已经执行过了,则判定该对象已经失效;若有finalize()方法且未执行过则进行第二次标记筛选

<3.第二次标记 & 筛选

在上一轮筛选结果中,放到一个 F-Queue 队列中,并由虚拟机自动建立、优先级低的Finalizer 线程去执行 队列中该对象的finalize(),在执行finalize()过程中,若对象依然没与引用链上的GC Roots 直接关联或间接关联,那么该对象将被判断死亡等待回收

finalize()只会被执行一次

参考

https://www.jianshu.com/p/108ddab3ad3f

 

### 判断Java线程是否存活Java中,`Thread` 类提供了 `isAlive()` 方法来检查线程是否仍然活着。然而,此方法需要一个 `Thread` 对象作为操作目标。要通过线程ID判断线程是否存活,则稍微复杂一些,因为标准API并不直接支持仅通过线程ID查询其状态的功能。 为了实现这一功能,可以创建一个映射表(Map),其中键为线程ID而值为对应的 `Thread` 实例,在启动新线程时将其注册到该映射表中[^1]。当想要检查某个特定ID的线程是否存活时,可以从映射表中检索相应的 `Thread` 对象并调用 `isAlive()` 方法: ```java import java.util.concurrent.ConcurrentHashMap; public class ThreadManager { private static final ConcurrentHashMap<Long, Thread> threadRegistry = new ConcurrentHashMap<>(); public static void register(Thread t) { threadRegistry.put(t.getId(), t); } public static boolean isThreadAlive(long id) { Thread t = threadRegistry.get(id); return t != null && t.isAlive(); } } ``` 对于上述代码片段中的 `register` 函数应在每个线程初始化后立即调用以确保能够正确记录所有活动线程的信息;而对于 `isThreadAlive` 函数则可以在任何地方用来验证给定ID所代表的线程当前是否处于活跃状态。 需要注意的是这种方法依赖于应用程序自行维护线程与其唯一标识之间的关联关系,并不是一种内置机制。因此,在实际应用开发过程中应当谨慎考虑这种设计模式所带来的潜在风险以及性能开销等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值