4 Java 如何判定是否存活或者死亡

九路 等级 847 0 0
标签: 后端

在堆中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事就是要确定这些对象之中哪些还活着,哪些对象已经死去. 判断对象是否已经死亡有以下几种算法:

引用计数法算法

  • 定义 : 给对象中添加一个引用计数器,当有一个地方引用时,计数器加1,引用失效时,就减1,当对象的引用计数器为0时,对象就是不可再被使用的. 特点 : JAVA虚拟机中很少使用这种算法,主要原因是它很难解决对象之间的循环引用问题

    可达性分析算法

  • 定义 : 通过一系列的称为 GC Roots 的对象作为起点,从这些节点开始向下搜索,搜索把走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连(就是从GC Roots 到这个对象不可达)时,则证明此对象是不可用的.如下图

4 Java 如何判定是否存活或者死亡

上图中的 5,6,7 对象就是不可达的,就是不可用的.

1) 哪些对象可以作为 GC Roots 对象呢? 1 虚拟机栈(栈帧中的本地变量表)中引用的对象 2 方法区中类静态属性引用的对象 3 方法区中常量引用的对象 4 本地方法栈中JNI引用的对象

2) 再谈引用:(从上到下依次减弱) 1 强引用 : 只要强引用还存在,垃圾收集器永远不回收被引用的对象 2 软引用 : 在内存溢出异常之前,回收对象 3 弱引用 : 在下一次 GC 时,无论当前内存是否足够,都会回收被引用的对象 4 虚引用 : 没用,唯一的用处是在对象回收时,会收到一个系统通知

3) 对象的 finalize() 方法作用 生存还是死亡? 即使在可达性分析算法中不可达的对象,也并非是"非死不可"的,这时候它们暂时处于"缓刑"阶段,要真正宣告一个对象死亡,至少要经历2次标记:

  • 1 如果对象在进行可达性分析后发现对象不可达,那它将会被第一次标记并进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法.当对象没有覆盖finalize()方法,或者finalize()方法已经执行过,虚拟机将这种情况视为没有必要执行

  • 2 如果对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queue的队列之中,并在稍后由一个由虚拟机自动建立的,低优先级的Finalizer线程去执行它.这里所谓的招行是指虚拟机会触发这个方法,但并不承诺等待它运行结束,这样做的原因是,如果一个对象在finalize()方法中做耗时的操作,将很可能会导致 F-Queue队列中的其它对象永久处于等待,甚至导致整个内存回收系统线程崩溃, finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次标记,如果对象要在finalize()中成功拯救自己,即只要对象重新和引用链上的任何一个对象发生关联即可,即将自己(this关键字)赋值给某个类变量或者对象的成员变量,那么在第二次标记时它将被移出"即将回收"的集合,如果对象这时候还没有逃脱,那么基本上它真的要被回收了 注:尽量不要用finalize()方法,忘了这个方法

收藏
评论区

相关推荐

Java核心技术 之安装环境 踏出第一步
Java JDK安装与配置 1、下载 官网地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html (1)点击DOWNLOAD 这里写图片描述(https://imghelloworld.osscnbeijing.aliyuncs.com/4
JDK核心JAVA源码解析(4)
想写这个系列很久了,对自己也是个总结与提高。原来在学JAVA时,那些JAVA入门书籍会告诉你一些规律还有法则,但是用的时候我们一般很难想起来,因为我们用的少并且不知道为什么。知其所以然方能印象深刻并学以致用。 本篇文章针对堆外内存与DirectBuffer进行深入分析,了解Java对于堆外内存处理的机制,为下一篇文件IO做好准备 Java堆栈内存与堆外内
Java 之路 Day3 JAVA环境的搭建
JAVA环境的搭建 ========= * * * 卸载JDK(了解JDK环境的组成) ----------------- 1. 删除Java的安装目录 2. 删除JAVA\_HOME 3. 删除path下关于Java的目录 4. 通过cmd打开dos窗口检测java-version是否删除 安装JDK
Java 编程基础
**Java 历史**      1995年5月23日,Java语言诞生 **1996年1月,第一个JDK(JDK1.0)诞生 **1996年4月,10个最主要的操作系统供应商申明将在其产品中嵌入JAVA技术 1996年9月,约8.3万个网页应用了JAVA技术来制作 1997年2月18日,JDK1.1发布 1997年4月2日,JavaO
Java复制文件的4种方式
### 1\. 使用FileStreams复制 这是最经典的方式将一个文件的内容复制到另一个文件中。 使用FileInputStream读取文件A的字节,使用FileOutputStream写入到文件B。 这是第一个方法的代码: private static void copyFileUsingFileStreams(File source, F
Java多线程之并发锁
**这是自JDK5.0开始提供的Java并发包里面的类** **下面是关于Java并发锁的测试代码** 1. **package** com.jadyer.thread.lock;   3. **import** java.util.concurrent.locks.Lock;   4. **import** java.util.concurre
Java并发指南4:Java中的锁 Lock和synchronized
**本文转载自并发编程网,侵删** 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 > [https://github.com/h2pl/Java-Tutorial](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fgithub.com%2
Java并发系列4
今天讲另一个并发工具,叫读写锁。读写锁是一种分离锁,是锁应用中的一种优化手段。 考虑读多写少的情况,这时如果我们用synchronized或ReentrantLock直接修饰读/写方法未尝不可,如: public static class Rw { private int val; public synchr
Java的4种代码块
往期精选   ●  [架构师高并发高性能分布式教程](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzAxNDMwMTMwMw%3D%3D%26mid%3D2247486245%26idx%3D1%26sn%3D7a28525
Java面试笔记整理4
一.Java内存溢出的产生原因和解决办法? java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产生该错误的原因大都出于以下原因:JVM内存过小、程序不严密,产生了过多的垃圾。 导致OutOfMemoryError异常的常见原因有以下几种: 1. 内存中加载的数据量过于庞大,如一次从数据库取出过多数据; 2.
jadis操作redis
[Java中使用Jedis操作Redis](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fwww.cnblogs.com%2Fliuling%2Fp%2F2014-4-19-04.html) =================================================
java基础常见面试题,这是一篇超长的随笔!!!
1\. Java基础部分....................................................... 4 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?.. 4 2、Java有没有goto?................................................. 4
java学习第一步
Java SE 磨刀不误砍柴工,工欲善其事必先利其器,咱们先搞好硬件配置,才能顺利的搞好Java学习 阶段一 1、认识Java 2、java发展史及用户 3、配置Java环境 4、JDK8下载安装 5、配置环境变量     JAVA\_HOME配置         java\_home配置两种方法:                 1、J
JSONTools Validator的使用
1. **此包的主要用途:** 2. **Parser**: Parse JSON text files and convert these to a Java model. 3. **Renderer**: Render a Java representation into text. 4. **Serializer*
Spring 4 支持的 Java 8 特性
> 【编者按】不管现在你是不是拒绝的,Java 8 越来越近了,各主流框架纷纷推出了支持 Java 8 的新版本,比如 [Spring](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fgithub.com%2Fspring-projects%2Fspring-framework%23pre