jvm 判断对象是否已经死亡

JVM的GC如何判断对象是否死亡? 因为热爱,所以坚持 文章下方有本文参考电子书和视频的下载地址哦~ 这节我们主要讲垃圾收集的一些基本概念,先了解垃圾收集是什么、然后触发条件是什么、最后虚拟机如何判断对象是否死亡。 一、前言   我们都知道Java和C++有一个非常大的区别就是Java有自动的垃圾回收机制,经过半个多世纪的发展,Java已经进入了“自动化”时代,让使用者只需要注重业务逻辑的开发而不需要担心内存的使用情况。那么我们为什么还要学习Java的垃圾回收机制呢?原因很简单:我们不想止于“增删改查工程师”这样的初级水平,一旦程序发生了内存溢出、内存泄漏等问题时,我们可以用已掌握的知识更好的调节和优化我们的代码。在学这章节之前 立即下载

如何判断java对象已经死亡?

容易想到的就是引用计数算法,就说的是给对象添加一个引用计数器,每当有一个地方引用到他,就加1;引用失效就减1。但是这样做是有问题的。
看下例子:

public class ReferenceCountingGC {
    public Object instace = null;
//  一个200M的对象
    private byte[] bigSize = new byte[200*1024*1024];

    public static void main(String[] args) {
//      引用加1
        ReferenceCountingGC a = new ReferenceCountingGC();
        ReferenceCountingGC b = new ReferenceCountingGC();
//      引用再加1
        a.instace=b;
        b.instace=a;
//      如果是引用计数,那么a,b的引用为2
//      在这里a,b减1
        a = null;
        b = null;
//      那么在这里ab引用都不是0,应该不可以回收
        System.gc();
        sleep(30);
    }
    public static void sleep(int second){
        try {
            Thread.sleep(second*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

debug,通过VisualVM发现,内存仍然被回收了。
这里写图片描述
,所以JVM不是通过引用计数的方式来确定是否回收对象的。因为,引用计数从上面的例子看出来会有一个问题就是,虽然还有引用,但这两个对象都是不可达对象(无法被访问的)。
所以java的垃圾回收不是采用这种简陋的引用计数来实现的。

可达性分析算法

java是通过可达性分析(Reachability Analysis)算法来判断对象是否存活。
其基本思想是通过一系列“”GC Roots“”的对象为起始点,从这些节点向下搜索,搜索所走过的路称为引用链,当一个对象没有任何引用链相连时,则证明该对象是不可引用的。如图(o1,o2,o3为不可达对象):
这里写图片描述

GC Root对象

1.虚拟机栈中引用的对象。
2.方法区中类静态属性引用的对象。
3.方法区常量引用的对象。
4.本地方法栈中JNI引用的对象。

引用分类

强引用(StrongReference),软引用(SoftReference),弱引用(WeakReference)以及PhantomReference(虚引用)
1.如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
2.软引用他的特点是当内存足够时不会回收这种引用类型的对象,只有当内存不够用时才会回收。
3.弱引用的作用在于解决强引用所带来的对象之间在存活时间上的耦合关系。弱引用最常见的用处是在集合类中,尤其在哈希表中。哈希表的接口允许使用任何Java对象作为键来使用。当一个键值对被放入到哈希表中之后,哈希表对象本身就有了对这些键和值对象的引用。
4.虚引用的特点是只要GC一运行就会把他给回收了,但会得到一个系统通知。

不可达对象就一定死亡吗?

其实不可达对象也并非是‘’非死不可‘’,但是他们已经处于缓刑状态。
要真的宣布一个对象死亡要经过两次标记过程:第一次标记并且筛选,筛选的条件是是否有必要执行了finalize方法。如果该类重写了该方法,并且没有执行过,那么该方法将会被执行。如果该方法执行完成,对象又重新和GCRoot关联上(把自己的引用给GCRoot),那么他在下一次GC时就不会被回收。
具体来看一个例子。

public class FinalEscapeGC {
    public static FinalEscapeGC obj = null;
    public void isAlive(){
        System.out.println("yes I'm still alive");
    }
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize method executed!");
        FinalEscapeGC.obj = this;
    }
    /**
     * finalize method executed!
        yes I'm still alive
        no I'm dead!
     */
    public static void main(String[] args) throws InterruptedException {
        obj = new FinalEscapeGC();
//      第一次GC自救成功
        obj = null;
        System.gc();
//      finalize方法优先级很低,因此要等他执行,不行还没执行就被回收了
        Thread.sleep(500);
        if(obj == null)
            System.out.println("no I'm dead!");
        else
            obj.isAlive();

//      第二次自救失败
        obj = null;
        System.gc();
        Thread.sleep(500);
        if(obj == null)
            System.out.println("no I'm dead!");
        else
            obj.isAlive();
    }

}

这个例子说明两点:
1,finalize方法是对象最后一个活下去的机会;
2,机会只能使用一次。
警告:finalize方法知道就行,千万别用,可以使用finally代替
总结:
完整的从JVM垃圾回收的角度分析了对象是否死亡,对象是否该回收等知识点。要点:使用可达性分析算法发现对象是否可回收,GCRoot引用有哪些。引用的分级,finalize方法啥时候调用。

lisflood-fp(一)从源码到可执行文件:Windows下的Cmake实战编译指南 本文详细介绍了在Windows环境下使用Cmake工具编译lisflood-fp水文模型源码生成可执行文件的全过程。从开发环境配置、源码获取到实战编译,逐步指导如何解决常见错误并处理运行时依赖,最终生成可用的exe文件。特别适合水文专业研究者和工程师学习参考。 阅读详情

相关推荐

(RegionProposal Network)RPN网络结构及详解

RPN(RegionProposal Network)区域生成网络 Faster-RCNN的核心。在这里整理。 1.anchors。 特征可以看做一个尺度51*39的256通道图像,对于该图像的每一个位置,考虑9个可能的候选窗口:三种面积{128,256,512}×{128,256,512}×三种比例{1:1,1:2,2:1}{1:1,1:2,2:1}。这些候选窗口称为anchors...

凹酱的DEEP LEARNING 19万+

(新手必看)HashMap是什么?

那么HashMap什么时候进行扩容呢?当hashmap中的元素个数超过数组大小*loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75,也就是说,默认情况下,数组大小为16,那么当hashmap中元素个数超过16*0.75=12的时候,就把数组的大小扩展为2*16=32

xyk:的博客 1万+

空地多无人平台协同路径规划复现:从建模到Matlab仿真全解析

路径规划是机器人领域的核心基础技术,从单机避障到多平台协同,问题复杂度显著提升。空地协同规划融合无人机与无人车的异构优势,通过将地图分层建模为空中与地面栅格,并采用A*算法生成初始路径、B样条平滑以及改进遗传算法进行任务分配与时间同步优化,能够有效处理几何约束、运动学约束和避碰约束等。该技术广泛应用于区域巡逻、目标搜索、物资转运等任务场景,也是高校论文复现和工程仿真的常见课题。本文从问题建模、算法设计到Matlab代码结构,系统梳理了一套空地多无人平台协同路径规划的复现思路,同时给出坐标系校准、遗传算法收敛

weixin_32175665的博客 248

HashMap详解

一、HashMap集合简介 HashMap 基于哈希表的 Map 接口实现,是以 key-value 存储形式存在,即主要用来存放键值对。HashMap 的实现不是同步的,这意味着它不是线程安全的。它的 key、value 都可以为 null,此外,HashMap 中的映射不是有序的。 jdk1.8 之前 HashMap 由 数组 + 链表 组成,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突(两个对象调用的 hashCode 方法计算的哈希值经哈希函数算出来的地址被别的元素占用)而存

java123456111的博客 5万+

硬件-汽车电子-TBOX/TCAM核心器件选型与系统集成设计指南

本文深入解析汽车电子TBOX/TCAM硬件架构与系统集成设计,涵盖核心器件选型、电源管理、信号完整性优化等关键点。重点分享5G模组选型避坑经验、MCU隐性指标及热设计验证方案,为车载通信系统开发提供实用指南。

weixin_30352645的博客 530

【NLG】(六)文本生成评价指标—— ROUGE原理及代码示例

前奏: 【NLG】(一)文本生成评价指标——BLEU原理及代码示例 【NLG】(二)文本生成评价指标—— METEOR原理及代码示例 【NLG】(三)文本生成评价指标—— ENTROPY原理及代码示例 【NLG】(四)文本生成评价指标—— diversity原理及代码示例 【NLG】(五)文本生成评价指标—— kl_divergence原理及代码示例 1.ROUGE原理 2.优缺点 3.如何算ROUGE ...

凝眸伏笔的博客 1万+

HashMap详解 Java [ 基础 ] ✅

HashMap是Java中一个强大且高效的集合类,用于快速查找和存储键值对。理解其工作原理和常用操作对于提高编程效率和解决复杂问题非常有帮助。

lenyan~的博客 2万+

基于Codex平台与AI Agent技能开发,实现抖音爆款视频分析与脚本自动生成

大家好,我是专注于AI应用开发的技术博主。最近在探索如何利用AI工具自动化内容创作时,我发现了一个非常有趣的组合:通过Codex平台创建自定义的Skill(技能),来批量分析抖音平台的爆款视频,并基于分析结果自动生成新的带货视频脚本。这听起来像是内容团队的“黑科技”,但实现起来其实有清晰的路径可循。本文将为你完整拆解这个实战项目,从环境搭建、Skill编写、数据抓取到视频脚本生成,手把手教你打造自己的“AI内容助理”。无论你是想了解AI Agent的开发,还是对短视频自动化创作感兴趣,都能从本文中获得可直接

weixin_34110749的博客 644

HashMap在jdk1.7和jdk1.8中的区别

一、初窥HashMap HashMap是应用更广泛的哈希表实现,而且大部分情况下,都能在常数时间性能的情况下进行put和get操作。 jdk1.7中底层是由数组(也有叫做“位桶”的)+链表实现;jdk1.8中底层是由数组+链表/红黑树实现 可以存储null键和null值,线程不安全。在HashMap中,null可以作为键,这样的键只有一个,但可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示HashMap中没有该key,也可以表示该key所对应的value为null。因

qq_34325438的博客 2601

C++/WinRT入门指南:现代Windows原生开发的核心技术

Windows运行时(WinRT)是微软为现代Windows应用开发设计的一套跨语言API框架,它基于COM技术原理构建,提供了统一的二进制接口标准。这项技术的核心价值在于让开发者能够以原生性能调用系统级功能,同时保持跨语言兼容性。在工程实践中,C++/WinRT作为官方推荐的C++语言投影,通过标准C++语法封装WinRT API,显著降低了开发复杂度。特别是在异步编程场景中,结合C++20协程特性,能够大幅提升代码可读性和维护性。对于需要高性能图形处理、系统集成或跨平台兼容的桌面应用开发,掌握C++/W

weixin_33910191的博客 1196

基于业务目标的Agent自动化评测体系设计:超越准确率的有效性衡量

我们还是以电商全链路服务Agent我们还是以电商全链路服务Agent。

AI架构全栈开发实战笔记 318

jvm如何判断对象是否死亡?

一、对垃圾收集的思考 垃圾收集并不是Java语言的伴生产物,实际上,垃圾收集的历史远远比Java久远,在1960年诞生于麻省理工的Lisp是第一门开始使用内存动态分配和垃圾收集技术的语言。当Lisp还是胚胎时期时,其作者John McCarthy就思考过垃圾收集需要完成的三件事情: 哪些内存需要回收? 什么时候回收? 如何回收 虽然今天的内存动态分配与内存回收技术已经相当成熟,一切看起来都进入了“自动化”时代,但当需要排查各种内存溢出、内存泄露问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就必须

初栀的博客 357

热力学仿真软件:Fluent_(8).材料属性设置

在 Fluent 中,材料属性主要包括密度、比热容、导热系数、黏度等物理性质。这些属性在不同的仿真场景中有着不同的作用,例如在流体仿真中,密度和黏度是必不可少的;在传热仿真中,导热系数和比热容是主要考虑的因素。如果所需的材料不在材料库中,或者需要对现有材料进行修改,用户可以自定义材料属性。在主菜单中选择Materials。点击打开材料编辑器。在材料编辑器中,点击Create按钮,输入新的材料名称。选择材料类型(如FluidSolid等)。在属性栏中填写所需的材料属性。

kkchenjj的博客 1492

「 JVM 」Java虚拟机是如何判断对象是否死亡的?

我们都知道Java和C++有一个非常大的区别就是Java有自动的垃圾回收机制,经过半个多世纪的发展,Java已经进入了“自动化”时代,让使用者只需要注重业务逻辑的开发而不需要担心内存的使用情况。那么我们为什么还要学习Java的垃圾回收机制呢?原因很简单:我们不想止于“增删改查工程师”这样的初级水平,一旦程序发生了内存溢出、内存泄漏等问题时,我们可以用已掌握的知识更好的调节和优化我们的代码。方法区、Java堆、虚拟机栈、本地方法栈、程序计数器。试想一下,GC(垃圾回收机制)在清理内存的时候第一件事要做什么。

frozenpenguin的博客 1373

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

JVM-判断对象是否死亡

总:对堆垃圾回收前的要判断哪些对象已经死亡(即不能再被任 何途径使用的对象)。两种方法:引用计数法和可达性分析算法。 一.引用计数法:给对象中添加一个引用计数器,引用一次,加1;引用失效,计数器减1;计数器为0的对象是不可能再被使用的。 注意:不被主流虚拟机使用,因为要考虑很多情况。比如两个没用的对象相互循环引用,A引用B,B引用A。 二.可达性分析算法:通过一系列的称为 “GC Roots” 的对象作为起点,从这些节点向下搜索, 节点所走过的路径称为引用链,当一个对象到 GC Roots

weixin_43227536的博客 229

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

判断JVM对象是否死亡

引用计数法 存在循环引用问题。 Redis是通过循环引用判断对象是否死亡的。 可达性分析 从GC Roots向下不可达时,证明此对象是不可能再使用的。 GC Roots的对象: JVM栈中的对象。 本地方法栈(native方法)中的对象。 方法区中静态引用的对象,如static final修饰的对象。 方法区中常量引用的对象,如字符串常量池里的引用。 被同步锁(synchronized)持有的对象。 … 引用类型 传统的“引用”定义:如果reference类型的数据中存储的数值代表的是另外一块内存的起始

weixin_48096939的博客 192

jvm判断对象是否死亡

方法有两种:引用计数法和可达性分析算法 引用计数法       在对象中添加一个引用计数器,每有一个地方引用它,引用计时器就加一。当引用计数器为0,即没有引用指向该对象的时候,就表示对象死亡。目前主流的虚拟机均没有采用这个算法来管理内存,因为它不能解决对象循环引用的问题,比如说:对象A和B相互引用着对方,但是再没有其它引用指向它们。所以它们的引用计数器值一直为1。垃圾回收器就无法回收它们。 可达性分析算法         算法的思

weixin_43312993的博客 178

JVM中如何判断对象是否死亡

有两种方法: 1.引用计数器算法: 给对象添加一个引用计数器,每当有一个地方引用它时,引用计数器加一,当引用失效时,计数器值减一;任何时刻对象的引用计数器为0的对象就是不可能再被使用的; 2.可达性算法分析: GC Roots 不可达的对象即为不可能再被引用的对象,即使这个对象可能还与其他对象有联系 两种算法区别: 怎么说呢,引用计数器算法针对相互引用的对象是不会发现的,,也就是他们的

jane_fast的博客 1723

判断是否存在此对象_JVM的垃圾回收机制,判断对象是否死亡

这节我们主要讲垃圾收集的一些基本概念,先了解垃圾收集是什么、然后触发条件是什么、最后虚拟机如何判断对象是否死亡。一、前言我们都知道Java和C++有一个非常大的区别就是Java有自动的垃圾回收机制,经过半个多世纪的发展,Java已经进入了“自动化”时代,让使用者只需要注重业务逻辑的开发而不需要担心内存的使用情况。那么我们为什么还要学习Java的垃圾回收机制呢?原因很简单:我们不想止于“增删改查工程...

weixin_33180221的博客 109

JVM(java)如何判断对象是否死亡?

虚拟机回收对象之前首先要判断对象是否死亡,两种方法:引用计数器法和可达性分析算法。 引用计数器法:给对象添加一个引用计数器,每当有一个地方引用它,计数器就加1,当引用失效时,计数器就减1,任何时刻当计数器为0的时候,这个对象就不能再被使用了。优点:实现简单效率高。缺点:主流jvm不使用这个算法,因为无法解决对象循环引用的问题。 可达性分析算法:首先有一系列的“GC roots”根节点,从根节点向下搜索,走过的路径叫做引用链,当一个对象到GC root没有任何引用链的时候,证明对象是不可活的(就是这个对象

qq_38197844的博客 782

深入理解JVM--如何判断对象是否死亡

深入理解JVM--如何判断对象是否死亡概述引用计数法可达性分析算法 概述 堆中几乎放着所有的对象实例,对堆垃圾回收前的第一步就是要判断那些对象已经死亡(即不能再被任何途径使用的对象) 引用计数法 给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加1;当引用失效,计数器就减1;任何时候计数器为0的对象就是不可能再被使用的。 这个方法实现简单,效率高,但是目前主流的虚拟机中并没有选择这个算法...

wuzhenwei0419的博客 305

jvm学习笔记:第3章java判断对象是否死亡

3.2.2 根搜索算法 在主流的商用程序语言中(Java和C#,甚至包括前面提到的古老的Lisp),都是使用根搜索算法(GC Roots Tracing)判定对象是否存活的。这个算法的基本思路就是通过一系列的名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话

宇宙神帝 1856

jvm垃圾回收机制_JVM的垃圾回收机制,判断对象是否死亡

这节我们主要讲垃圾收集的一些基本概念,先了解垃圾收集是什么、然后触发条件是什么、最后虚拟机如何判断对象是否死亡。一、前言我们都知道Java和C++有一个非常大的区别就是Java有自动的垃圾回收机制,经过半个多世纪的发展,Java已经进入了“自动化”时代,让使用者只需要注重业务逻辑的开发而不需要担心内存的使用情况。那么我们为什么还要学习Java的垃圾回收机制呢?原因很简单:我们不想止于“增删改查工程...

weixin_39684898的博客 95

为什么jvm不使用引用计数算法来判断对象是否已经死亡

在堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着 ,哪些已经“死去”(即不可能再被任何途径使用的对象)。 引用计数算法 很多教科书判断对象是否存活的算法是这样的:给对象中添加一个引用计数器,每当有—个地方引用它时,计数器值就加1 ; 当引用失效时,计数器值就减1 ; 任何时刻计数器为0的对象就是不可能再被使用的。 客观地说,引用计数算法( Reference Counting ) 的实现简单,判定效率也很高,在大部分情况下它都是一个

zty 842

【深入理解jvm读书笔记】如何判断一个java对象是否已经死亡

当前主流的商用程序语言(Java、C#,上溯至前面提到的古老的Lisp)的内存管理子系统,都是通过可达性分析(Reachability Analysis)算法来判定对象是否存活的。缺点:占用了一些额外的内存空间,这个看似简单的算法有很多例外情况要考虑,必须要配合大量额外处理才能保证正确地工作,譬如单纯的引用计数就很难解决对象之间相互循环引用的问题。根据用户所选用的垃圾收集器以及当前回收的内存区域不同,还可以有其他对象“临时性”地加入,共同构成完整GC Roots集合。,搜索过程所走过的路径称为。

Ez4Sterben的博客 195
上一篇: 使用netty+zookeeper+protobuf实现一个RPC过程
下一篇: java常用位操作
Next__One
博客等级 码龄9年 14粉丝 62原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值