JVM对象存活判断方法

一、GC主要针对什么区域

  1. 程序计数器、虚拟机栈、本地方法栈,3个部分随线程而生死。每个栈桢分配多少内存基本上是在类结构确定下来时就已确定,大体上可认为是 编译期可知。

  2. 而 堆 和 方法区 则不一定,如一个接口多个实现类需要内存不一样,一个方法多个分支需要分配内存也不一样;这些只有一实现运行中才能得知会创建那些对象,这部分内存的分配 和 回收 都是动态的。GC主要关注的也是这两个部分。

二、对象的“存活”:

  1、引用计数法:在各个对象中添加一个引用计数器。

    a. 实现简单,判定效率高;

    b. 但主流JVM没有用这个方法来判定;主要因为它很难解决对象间的相互循环引用问题。

  2、可达性分析算法:

    a. 主流的程序语言使用的方法。

    b. 通过GC Roots的对象作作为起点,从这些起点向下去搜索,所走过的路径叫做引用链,当一个对象到GC Roots没有任何引用链连接时,则证明此对象不可达。

    c. 可作为GC Roots的对象:

      1. 方法区中类静态属性、常量引用的对象;(Static修饰)

      2. 虚拟机栈、本地方法栈中引用的对象;

三、最终判定对象是否被回收:

  在可达性分析算法中不可达的对象,也并非就判定为“死亡”了;判定一个对象最终是否死亡,至少经历两次标记过程:

    1. 不可达的对象会被 第一次标记;

    2. 被第一次标记的对象进行 判断是否有必要执行finalize(),若对象覆盖了finalize()方法 且 finalize() 没有执行过,若都满足则执行finalize();

    3. 在finalize()中,若对象重新和引用链上的任一对象建立关联,则不会被第二次标记,它则不会被回收。

时间: 2024-10-07 09:41:37

JVM对象存活判断方法的相关文章

JVM【第十三回】:【Java对象存活------finalize()方法】

在根搜索算法中不可达的对象,也并非是"非死不可"的,这个时候他们暂时处于"缓刑"阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行根搜索后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是对象是否有必要执行finalize()方法.当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为"没有必要执行". 如果这个对象被判定为有必要

判断对象存活的方法

1. 引用计数法:给对象添加一个引用计数器,每当一个地方引用它,计数器值加1:当引用失效时,计数器值就减1 2. 可达性分析法:当一个对象到GC Roots没有任何引用链相连时,该对象被判断为可回收的对象,主流方法 可作为GC Roots对象的: (1)虚拟机栈中引用的对象(栈帧中的本地变量表): (2)方法区中的静态属性引用的对象: (3)方法区中常量引用的对象: (4)本地方法栈中JNI(即一般说得native方法)引用的对象 3. 引用类型法:强引用,软引用,弱引用,虚引用

JVM高级特性与实践(二):对象存活判定算法(引用) 与 回收

关于垃圾回收器GC(Garbage Collection),多数人意味它是Java语言的伴生产物.事实上,GC的历史远比Java悠远,于1960年诞生在MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言.当Lisp尚在胚胎时期,开发人员就在思考GC需要完成的3件事情: 哪些内存需要回收? 什么时候回收? 如何回收? 目前GC早已解决了以上问题,内存的动态分配与内存回收机制已经相当成熟,一切似乎“自动化”起来.而开发人员仍旧需要了解GC和内存分配等底层知识,因为在排查各种内存溢出.内

聊聊JVM(三)两种计算Java对象大小的方法

这篇说说如何计算Java对象大小的方法.之前在聊聊高并发(四)Java对象的表示模型和运行时内存表示 这篇中已经说了Java对象的内存表示模型是Oop-Klass模型. 普通对象的结构如下,按64位机器的长度计算 1. 对象头(_mark), 8个字节 2. Oop指针,如果是32G内存以下的,默认开启对象指针压缩,4个字节 3. 数据区 4.Padding(内存对齐),按照8的倍数对齐 数组对象结构是 1. 对象头(_mark), 8个字节 2. Oop指针,如果是32G内存以下的,默认开启对

JVM——对象已“死”的判定

主要针对Java堆和方法区 1.判断对象是否已"死" Java堆中存放着几乎所有的对象实例,垃圾回收器在对堆进行回收之前,首先应该判断这些对象哪些还"存活",哪些已经"死亡". (1)引用计数法 A. 工作流程 给每个对象附加一个计数器,每当有一个地方引用此对象.计数器+1:每当有一个地方不再引用此对象,计数器-1:在任意时刻,只要对象引用计数器值为0,任务此对象已经"死亡".(没有"死亡"的对象一定不会被

JVM对象分配和GC分布【JVM】

最近在学习java基础结构,刚好学到了jvm,总结了以下并可以结合思维导图认识以下Jvm的对象: 栈:什么是栈? 先说一下栈的数据结构吧,栈它是一种先进后出的数据结构(FILO),跟队列刚好相反(先进先出FIFO),生活中有哪些例子, 举个例子 给子弹上膛,上弹的操作就类似于栈的数据结构,先压入的子弹后发射,因为它被压入到了最底部(栈底),所以,它会先发射最上面的子弹(栈顶), 说了这个概念,想必应该已经熟悉了栈的数据结构了吧. 再说一下栈,栈相当于一个桶,里面有方法区,局部变量表,方法返回地址

JVM是如何进行方法调用的

在我们平时的工作学习中写java代码时,如果我们在同一个类中定义了两个方法名和参数类型都相同的方法时,编译器会直接报错给我们.还有在代码运行的时候,如果子类定义了一个与父类完全相同的方法的时候,父类的方法就会被覆盖,(也就是我们平时说的重写).那么,jvm虚拟机是如何精确识别目标方法的. 重载.重写与多态 重载:方法名相同而参数类型不相同的方法之间的关系. 重写:方法名相同并且参数类型也相同的方法之间的关系. 这两个概念我们耳熟能详,那么重载和重写是如何判断的呢? 重载: 重载的方法在编译期间就

自定义类型的对象如何判断相等

NSObject协议中有两个用于判断等同性的关键方法: - (BOOL)isEqual:(id)object; - (NSUInteger)hash; NSObject类对这两个方法的默认实现是:当且仅当其“指针值”(pointer value)完全相等时,这两个对象才相等.如果“isEqual:”方法判定两个对象相等,那么其hash方法也必须返回同一个值.但是,如果两个对象的hash方法返回同一个值,那么“isEqual:”方法未必会认为两者相等. 比如有下面这个类: @interface E

JVM总结(一):概述--JVM对象探秘

这一节我们来讨论一下JVM对象建立过程. JVM对象探秘 对象的建立 对象的内存布局 对象的访问定位 JVM对象探秘 对象的建立 对象的建立过程   图一:对象建立过程 1.类加载检查. 当JVM检测到有一条new指令时,首先先检查该指令的参数是否在常量池中定位到一个类的符号引用,并检查这个符号引用所代表的类是否已被加载.解析和初始化过.如果存在的话,JVM将直接使用已有的信息对该类进行操作. 如果没有,则执行相应的类加载过程. 2.为新生对象分配内容. 不同的JVM垃圾收集器在内容分配的时候的