我们知道Java中的对象一般存放在堆中,但是总不能让这些对象一直占着内存空间,这些对象最终都会被回收并释放内存,那么我们如何判断对象已经成为垃圾呢?这篇文章会提出两种算法解决这个问题。另外,本文还要谈一谈对象引用相关的知识,这在面试中也是经常被问到的问题。

判断对象是否存活算法

引用计数算法

引用计数算法的原理比较简单,在对象中添加一个引用计数器,当有一个引用指向一个对象时,这个对象的引用计数器会加1,当引用不再指向对象时,引用计数器便减1。当引用计数器的值为0时,说明对象已经成为垃圾。

引用计数算法的优点是算法非常简单,效率也比较高。但是Java并没有使用这种算法管理内存,这是为什么呢?我们先来看看下面这段代码。

public class Demo {

public static void main(String[] args) {

Obj obj1 = new Obj();

Obj obj2 = new Obj();

obj1.instance = obj2;

obj2.instance = obj1;

obj1 = null;

obj2 = null;

}

}

class Obj {

public Obj instance;

public Obj() {

super();

}

}

我们看一下上面这段代码,两个对象obj1和obj2的instance分别指向对方,造成了循环引用。即便最后obj1和obj2都置为空,但它们的instance还是指向对方,如果我们使用这种算法,这两个对象势必无法回收,最终造成内存泄漏。因此,Java没有选择使用引用计数算法管理内存。

可达性分析算法(根搜索算法)

主流的商用编程语言(Java、C#以及上古语言Lisp)都是用这种算法进行对象是否存活的判断。

根搜索算法利用GC Roots作为起始节点集,从这些节点开始向下搜索,凡是能够到达的节点都是存活节点,不能到达的节点都不再会被使用,这些节点的对象都可以被回收。

Java技术体系中可以作为GC Roots的对象有以下几种:虚拟机栈(栈帧的本地变量表)中引用的对象

方法区中类静态属性引用的对象

方法区中常量引用的对象

本地方法栈中JNI(及native方法)引用的对象

虚拟机内部的引用,比如基本数据类型对应的Class对象,一些常驻的异常对象(如NullPointerException、OutOfMemoryError)等,还有类加载器。

被同步锁(synchronized)持有的对象

反映Java虚拟机内部情况的JMXBean、JVMTI注册的回调,本地代码缓存等

另外,需要补充的是,即便被可达性分析算法标记为不可达对象,这些对象也未必一定会被回收。事实上,被标记为不可达对象后,这个对象还需要经历第二次标记才可能会被宣布正式死亡。当第一次标记以后,会判断对象有没有必要执行finalize()方法。当对象没有覆盖finalize()方法或已经被虚拟机调用过的话,就被判定没有必要再继续执行了。当有必要执行finalize()方法时,这些对象会被放在名为F-Queue的队列中,随后虚拟机会创建一个线程去执行队列中的对象的finalize()方法。如果这些对象在收集器对F-Queue中对象标记前在finalize()方法中重新与引用链上的对象建立关系,比如将自己赋值给某个类变量就可以移出回收集合,免除被回收的命运。

对象引用

谈到引用,不得不提到前几天的考研复试,我的一位学弟在复试过程中被问到Java中有哪些引用,这几种引用有什么区别。被问到这道题时,他一时语塞,没有回答上来。不过好在没有因为这道题受到影响。今天我们就来谈一谈Java中的四种引用。强引用。强引用是我们平时使用最多的引用方法。Object obj = new Object()这就是一个典型的强引用实例,只要强引用关系还存在,即使系统内存不足,也不会回收这些对象。

软引用。软引用用来描述一些还有用,但不是必须的对象,使用SoftReference类来实现软引用。当系统内存不足时,会回收软引用关联的对象。

弱引用。弱引用通过WeakReference类来实现,即使内存充足,下一次垃圾收集时,弱引用对象也会被回收。

虚引用。虚引用又称“幽灵引用”或“幻影引用”,是最弱的一种对象引用,它使用PhantomReference类来实现。虚引用的作用是在关联的对象被回收时能收到一个系统通知。

喜欢的给个赞呗

了解更多可以关注我的公众号:SKY技术修炼指南

java中对象的生存期_深入理解Java虚拟机-判断对象是否存活算法与对象引用相关推荐

  1. java中io是什么_深入理解Java中的IO

    深入理解Java中的IO 转载自:http://blog.csdn.net/qq_25184739/article/details/51205186 本文的目录视图如下: Java IO概要 a.Ja ...

  2. java中的工厂模式_深入理解Java的三种工厂模式

    一.简单工厂模式 简单工厂的定义:提供一个创建对象实例的功能,而无须关心其具体实现.被创建实例的类型可以是接口.抽象类,也可以是具体的类 实现汽车接口 奔驰类 宝马类 简单工厂,既能生产宝马又能生产奔 ...

  3. java spring boot 注解验证_如何理解Java原生注解和Spring 各种注解?

    作者:digdeep .cnblogs.com/digdeep/p/4525567.html 导引 Spring中的注解大概可以分为两大类: spring的bean容器相关的注解,或者说bean工厂相 ...

  4. java中的static类_再议Java中的static关键字

    再议Java中的static关键字 java中的static关键字在很久之前的一篇博文中已经讲到过了,感兴趣的朋友可以参考:<Java中的static关键字解析>. 今天我们再来谈一谈st ...

  5. java中的invoke方法_详解Java中Method的Invoke方法

    在写代码的时候,发现从父类class通过getDeclaredMethod获取的Method可以调用子类的对象,而子类改写了这个方法,从子类class通过getDeclaredMethod也能获取到M ...

  6. java如果不使用多态_深入理解java多态没有烤山药的存在,java就不香了吗?

    @ 我不想知道各位理解java多态没有烤山药的存在,java香不香的问题了,我不要你们认为,我只要我觉得 (感觉要被打....) 在博主认为多态绝对是面向对象的第三大特性中让很多小白同学以及初学者难以 ...

  7. java方法区内存泄露_深入理解java虚拟机-第二章:java内存区域与内存泄露异常...

    2.1概述: java将内存的管理(主要是回收工作),交由jvm管理,确实很省事,但是一点jvm因内存出现问题,排查起来将会很困难,为了能够成为独当一面的大牛呢,自然要了解vm是怎么去使用内存的. 2 ...

  8. java中什么是类型_什么是Java中基本数据类型?

    Java中除了二进制文件和使用文本文件外还有基于Data的数据操作,这里的Data指的是Java的基本数据类型和String.基本数据类型包括byte.int.char.long.float.doub ...

  9. java中注解的解析_全面解析Java中的注解与注释

    注解一.什么是 Annotation? (注解 or 注释)Annotation, 准确的翻译应该是 -- 注解. 和注释的作用完全不一样. Annotation 是JDK5.0及以后版本引入的一个特 ...

最新文章

  1. 决策树(Decision Tree)原理
  2. 封装javascript分页插件——可以使用的测试版(β版)
  3. 河南多校大一训练赛 C 青蛙的约会
  4. app vue 真机运行_使用 HBuilder 将 Vue 项目打包成手机 App
  5. centos7 搭建keepalived+Nginx+tomcat
  6. 时间格式转换y-m-d
  7. 文字识别_文字识别的应用
  8. POJ 1703 Find them, Catch them(路径压缩并查集)
  9. 超标量体系结构_计算机体系结构——以多发射和静态调度来开发ILP
  10. 2020 CPU性能排行天梯图
  11. Windows系统下快速安装、配置Aira2,及图形界面配置、度盘、B站视频下载
  12. 如何集中远程管理各种USB设备,还不了解一下?
  13. 手机计算机怎么玩24点游戏,计算器上的24点游戏怎么操作
  14. python写Bicubic方法,跑数据集Set5和Set14,保存PSNR和SSIM的值
  15. html match函数,match函数的使用方法 match函数怎么使用
  16. 2023考研路上,恭祝诸君只争朝夕,不负韶华
  17. js和vue的图片加载完成事件
  18. Oracle中设置定时任务--执行sql
  19. 如何运用政务智慧引导系统提升群众办事效率
  20. WPF输入框双向绑定Decimal类等数据无法输入小数点

热门文章

  1. 从Mysql slave system lock延迟说开去
  2. SAP 免费赠与客户货物的销项税处理
  3. python 开发api_使用FastAPI和Python快速开发高性能API
  4. r a/b 测试_R中的A / B测试
  5. 5922. 统计出现过一次的公共字符串
  6. css网格_我如何记住CSS网格属性
  7. ios 跨域_如何在iOS和Android中建立跨域通信桥
  8. 需求简报_代码简报:我如何通过做自己喜欢的事情来获得顶级技术实习
  9. 项目经理如何管理情绪?这三本书管理书籍你必须要看
  10. Koa 中实现 chunked 数据传输