JVM——垃圾回收资格的判定
一:判断一个对象是否已死
1:引用数算法:给对象加个引用计数器,被引用时加一,引用失效减一,在任何时刻一直为0的就说明不会被使用,但是由于一种情况的存在,导致这种算法不被JVM所考虑,在两个对象相互引用用的时候,会出现计数一直为1的情况出现,如下代码所示:
public class Test {
public Object instance = null;
public static void main(String[] args) {
Test a = new Test();
Test b = new Test();
a.instance = b;
b.instance = a;
}
}
所以JVM不使用计数算法作为判断是否可回收的依据。
2:可达性分析算法:通过一系列的被称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索的路径称为引用链(Reference Chain),当一个对象到“GCRoots”没有任何引用链相连(从GCRoots到这个对象不可到达)时,则证明对象不可用,如图:

object 4,5,6虽然有互相关联,但是到GC Roots时不可达的,所以会被判定为时可回收对象。
在JAVA中,可作为GC Roots的对象包括以下几种:
- 虚拟机栈中局部变量表中引用的对象
- 本地方法栈中 JNI(一般说的Native方法) 中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中的常量引用的对象
3:引用类型:无论是通过引用计数算法判断对象的引用数量,还是通过可达性分析算法判断对象是否可达,判定对象是否可被回收都与引用有关。
1:强引用:
被强引用关联的对象不会被回收。
使用 new 一个新对象的方式来创建强引用。
Object obj = new Object();
2:软引用:用来描述一些还有用但非必须的对象,在内存不够的情况下回收,回收之后还是内存不足才会抛出内存溢出异常,使用 SoftReference 类来创建软引用:
Object obj = new Object();
SoftReference<Object> sf = new SoftReference<Object>(obj);
obj = null; // 使对象只被软引用关联
3:弱引用:也是用来描述非必需对象,但是只能生存到下一次垃圾回收,可使用WeakReference类来实现引用
Object obj = new Object();
PhantomReference<Object> pf = new PhantomReference<Object>(obj);
obj = null
4:虚引用又称为幽灵引用或者幻影引用,一个对象是否有虚引用的存在,不会对其生存时间造成影响,也无法通过虚引用得到一个对象。为一个对象设置虚引用的唯一目的是能在这个对象被回收时收到一个系统通知。使用 PhantomReference 来创建虚引用。
Object obj = new Object();
PhantomReference<Object> pf = new PhantomReference<Object>(obj);
obj = null;
4:最后的抉择:就算再可达性算法中不可达的对象,也不是非死不可的,要真正宣告死亡至少要经历两次标记过程:如果对象进行可达性分析后发现没有与GC Roots相连的引用链,就会被第一次标记并进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法,当对象没覆盖finalize()方法或者已经执行过finalize()方法,虚拟机将这两种情况都视作没有必要执行。如果判定为有必要执行的话,就会进入队列,等待触发finalize()方法,finalize()方法是对象最后一次拯救自己的机会,若是再第二次还没有逃脱,便死了。并且任何对象只能调用一次finalize()方法。
5:回收方法区:因为方法区主要存放永久代对象,而永久代对象的回收率比新生代低很多,所以在方法区上进行回收性价比不高。
主要是对常量池的回收和对类的卸载。
为了避免内存溢出,在大量使用反射和动态代理的场景都需要虚拟机具备类卸载功能。
类的卸载条件很多,需要满足以下三个条件,并且满足了条件也不一定会被卸载:
- 该类所有的实例都已经被回收,此时堆中不存在该类的任何实例。
- 加载该类的 ClassLoader 已经被回收。
- 该类对应的 Class 对象没有在任何地方被引用,也就无法在任何地方通过反射访问该类方法。
JVM——垃圾回收资格的判定的更多相关文章
- jvm - 垃圾回收
jvm - 垃圾回收 注意 : 本系列文章为学习系列,部分内容会取自相关书籍或者网络资源,在文章中间和末尾处会有标注 垃圾回收的意义 它使得java程序员不再时时刻刻的关注内存管理方面的工作. 垃圾回 ...
- 老李分享:jvm垃圾回收
老李分享:jvm垃圾回收 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478 ...
- Java虚拟机垃圾回收:内存分配与回收策略 方法区垃圾回收 以及 JVM垃圾回收的调优方法
在<Java对象在Java虚拟机中的创建过程>了解到对象创建的内存分配,在<Java内存区域 JVM运行时数据区>中了解到各数据区有些什么特点.以及相关参数的调整,在<J ...
- JVM内存管理、JVM垃圾回收机制、新生代、老年代以及永久代
内存模型 JVM运行时数据区由程序计数器.堆.虚拟机栈.本地方法栈.方法区部分组成,结构图如下所示. JVM内存结构由程序计数器.堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 1)程序计数器 ...
- JVM垃圾回收?看这一篇就够了!
深入理解JVM垃圾回收机制 1.垃圾回收需要解决的问题及解决的办法总览 1.如何判定对象为垃圾对象 引用计数法 可达性分析法 2.如何回收 回收策略 标记-清除算法 复制算法 标记-整理算法 分带收集 ...
- 【搞定Jvm面试】 JVM 垃圾回收揭秘附常见面试题解析
JVM 垃圾回收 写在前面 本节常见面试题 问题答案在文中都有提到 如何判断对象是否死亡(两种方法). 简单的介绍一下强引用.软引用.弱引用.虚引用(虚引用与软引用和弱引用的区别.使用软引用能带来的好 ...
- JVM——垃圾回收
目录: 如何判断垃圾是否回收? 引用计数法 可达性分析算法 四种引用 引用队列 垃圾回收算法 标记清除算法 复制算法 标记整理算法 分代垃圾回收 新生代 老年代 Minor GC 和 Full GC的 ...
- 二、JVM — 垃圾回收
JVM 垃圾回收 写在前面 本节常见面试题 本文导火索 1 揭开 JVM 内存分配与回收的神秘面纱 1.1 对象优先在 eden 区分配 1.2 大对象直接进入老年代 1.3 长期存活的对象将进入老年 ...
- JVM垃圾回收详解
通常,我们在写java程序的时候,似乎很少关注内存分配和垃圾回收的问题.因为,这部分工作,JVM已经帮我们自动实现了. 这样看起来,好像很美好,但是任何事情都有两面性.虽然JVM会自动的进行垃圾回收, ...
随机推荐
- 转:webpack代码压缩优化
压缩代码 18 天前30前端开发 压缩 JavaScript 修改 JavaScript 压缩处理器 其他压缩 JavaScript 的方法 加快 JavaScript 执行速度 作用域提升 预执行 ...
- TCP/IP和OSI4层、7层协议介绍
1.TCP/IP全称:Transmission Control Protocol / Internet Protocol 中文翻译:传输控制协议 / 互联网协议 2.OSI4层.7层模型:
- NET高级开发工程师职责要求
岗位职责1.参与架构以及核心业务的设计:2.使用简单,干净,可维护性高,扩展性好的代码实现产品功能,并在必要时重构现有代码:3.贯彻面向接口以及模块化组件的设计理念:4.熟练RabbitMQ.ES.M ...
- git本地以及远程分支回滚
转:https://www.cnblogs.com/sunny-sl/p/11236280.html 1. git本地版本回退 Git reset --hard commit_id(可用 git lo ...
- [UE4] TSharedPtr, TWeakObjectPtr and TUniquePtr
转自:https://dawnarc.com/2018/07/ue4-tsharedptr-tweakobjectptr-and-tuniqueptr/ UE4 的 TSharedPtr.TWeakO ...
- Difference between java.lang.RuntimeException and java.lang.Exception
In Java, there are two types of exceptions: checked exceptions and un-checked exceptions. A checked ...
- Django-12-auth认证组件
1. 介绍 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能. Django作为一个完美主义者的终极框架,当然也会 ...
- Python中使用@的理解
Python函数中使用@ 稍提一下的基础 fun 和fun()的区别 以一段代码为例: def fun(): print('fun') return None a = fun() #fun函数并将返回 ...
- 大数据之路【第十篇】:kafka消息系统
一.简介 1.简介 简 介• Kafka是Linkedin于2010年12月份开源的消息系统• 一种分布式的.基于发布/订阅的消息系统 2.特点 – 消息持久化:通过O(1)的磁盘数据结构提供数据的持 ...
- 【转】ZYNQ中三种实现GPIO的方式
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/husipeng86/article/det ...