大家都知道,JVM 有垃圾回收的机制,垃圾回收的前提是要知道:什么是垃圾!然后再是如何识别垃圾

什么是垃圾

垃圾,本质上就是没有引用的对象(们),下面来介绍两种垃圾

1. 没有引用指向的对象

下图是对象间引用的状态,从正常引用到引用断开,这个 A 和 C 的引用断开之后,C 就成了那个垃圾。

2. 没有引用指向的一组对象

一个典型的案例如下图,就是循环引用,这几个对象看起来都有引用指向,但是其实他们只是一堆紧紧相拥的垃圾。

如何识别垃圾

上面介绍了什么是垃圾,那要如何才能识别出垃圾呢?主要有两种算法:

  1. 引用计数法
  2. 可达性分析法

1. 引用计数法

算法很简单,就是在对象头上加上被引用的次数,对象的被引用的次数为 0 之日,就是其成为垃圾之时!这个算法的优点是垃圾回收及时,只要对象被引用次数为 0,就可以回收了。

下图是引用计数的示意图,对象 A、B、C 都被引用了一次

如果 A 跟 C 的引用断开,则 C 的引用次数减一,变为 0,此时 C 就是垃圾

引用计数法有个致命的缺点:那就是无法识别出循环引用!

下图是一个循环引用,明明他们就是一堆垃圾,但是因为被引用次数都不为 0,引用计数法无法识别出他们是垃圾。

2. 可达性分析法

引用计数法的缺点过于致命,目前 JVM 采用的是另一种算法来识别垃圾:可达性分析法。

这个算法的基本思路就是:从一系列根对象(GC Roots)开始,根据引用关系向下搜索,如果某个对象到 GC Roots 间没有任何引用,则证明此对象是不可能再被使用的,也就是垃圾。

其示意图如下,左边绿色部分的对象,都可以连向 GC Roots,所以他们都是存活的对象。而右边灰色的部分,即使他们是循环引用,他们也跟 GC Roots 之间没有连接路径,所以灰色部分的对象是垃圾。



那么,究竟是哪些对象能成为至高无上的 GC Roots 呢?以下是主要的 GC Roots:

  • 虚拟机中引用的对象,如各个线程调用的方法堆栈中的参数、局部变量等。
  • 方法区中类的静态属性引用的对象,如类的引用类型的静态变量。
  • 方法区中常量引用的对象,如字符串常量池里的引用。
  • 本地方法栈中 JNI(Native 方法)引用的对象。
  • 虚拟机内部的引用,如基本数据类型对应的 Class 对象,一些常驻的异常对象(比如 NullPointExcepitonOutOfMemoryError)等,还有系统类加载器。

优点:解决引用计数器所不能解决的循环引用问题。

缺点:

  1. 耗时:因为需要从 GC Roots 开始逐个检查引用;
  2. STW:GC 过程中需要保证对象的引用关系不能发生变化,所以 GC 进行时必须停顿所有执行线程(STW:Stop The World)。

总结

第一部分我们介绍了什么是垃圾:没有任何引用指向的一个或多个对象。

第二部分介绍了如何识别垃圾,有两种算法:

  1. 引用计数法:通过给对象添加被引用的次数来识别。优点是回收简单及时;缺点是无法解决循环引用。
  2. 可达性分析法:从一系列根对象(GC Roots)开始,根据引用关系向下搜索,如果某个对象到 GC Roots 间没有任何引用,则此对象就是垃圾。优点是解决了循环引用;缺点是耗时和 STW。

哦?原来这就是 JVM 垃圾!的更多相关文章

  1. JDK分析工具&JVM垃圾回收(转)

    转自:http://blog.163.com/itjin45@126/blog/static/10510751320144201519454/ 官方手册:http://docs.oracle.com/ ...

  2. JVM基础系列第8讲:JVM 垃圾回收机制

    在第 6 讲中我们说到 Java 虚拟机的内存结构,提到了这部分的规范其实是由<Java 虚拟机规范>指定的,每个 Java 虚拟机可能都有不同的实现.其实涉及到 Java 虚拟机的内存, ...

  3. JVM垃圾回收机制与内存回收

    暂时转于:https://blog.csdn.net/qq_27035123/article/details/72857739 垃圾回收机制 GC是垃圾回收机制,java中将内存管理交给垃圾回收机制, ...

  4. 图解JVM垃圾内存回收算法

    图解JVM垃圾内存回收算法 这篇文章主要介绍了图解JVM垃圾内存回收算法,由于年轻代堆空间的垃圾回收会很频繁,因此其垃圾回收算法会更加重视回收效率,下面博主和大家来一起学习一下吧 前言 首先,我们要讲 ...

  5. 深入JVM垃圾回收机制,值得你收藏

    JVM可以说是为了Java开发人员屏蔽了很多复杂性,让Java开发的变的更加简单,让开发人员更加关注业务而不必关心底层技术细节,这些复杂性包括内存管理,垃圾回收,跨平台等,今天我们主要看看JVM的垃圾 ...

  6. .Net平台GC VS JVM垃圾回收

    前言 不知道你平时是否关注程序内存使用情况,我是关注的比较少,正好借着优化本地一个程序的空对比了一下.Net平台垃圾回收和jvm垃圾回收,顺便用dotMemory看了程序运行后的内存快照,生成内存快照 ...

  7. JVM垃圾回收机制总结:调优方法

    转载: JVM垃圾回收机制总结:调优方法 JVM 优化经验总结 JVM 垃圾回收器工作原理及使用实例介绍

  8. JVM 垃圾回收器工作原理及使用实例介绍

    IBM介绍文档:https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/ Java 的新生代串行垃圾回收器中使用了复制 ...

  9. JVM 垃圾回收器工作原理及使用实例介绍(转载自IBM),直接复制粘贴,需要原文戳链接

    原文 https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/ 再插一个关于线程和进程上下文,待判断 http://b ...

随机推荐

  1. Git常用命令和基础使用

    Git 参考:廖雪峰的Git教程 Git 常用命令 git config --global user.name "name" #配置git使用用户 git config --glo ...

  2. JavaScript-编译与闭包

    编译原理 尽管 JavaScript 经常被归类为"动态"或"解释执行"的语言,但实际上它是一门编译语言.JavaScript 引擎进行的编译步骤和传统编译语言 ...

  3. 用Python预测双色球福利彩票中奖号码(请不要当真)

    前言 双色球是中国福利彩票的一种玩法. 红球一共6组,每组从1-33中抽取一个,六个互相不重复.然后蓝球是从1-16中抽取一个数字,这整个组成的双色球 python从零基础入门到实战 今天,我们就用P ...

  4. springboot 中 inputStream 神秘消失之谜

    序言 最近小明接手了前同事的代码,意料之外.情理之中的遇到了坑. 为了避免掉入同一个坑两次,小明决定把这个坑记下来,并在坑前立一个大牌子,避免其他小伙伴掉进去. HTTPClient 模拟调用 为了把 ...

  5. Vue3学习第一例:Vue3架构入门

    入门 Vue3的教程很少,官方网站实例不好整,另外由于Python的Django也掌握了,学习这个有些让人眼乱.Vue项目创建后,在public目录下面自动生成了一个index.htm,里面有个div ...

  6. 模拟input type=file

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Appium自动化测试(1)-安装&环境

    需要链接appium自动化测试教程 http://www.cnblogs.com/fnng/p/4540731.htmlappium中文文档:https://github.com/appium/app ...

  8. 【Android面试查漏补缺】之Handler详解,带你全面理解Handler消息机制

    在安卓面试中,关于 Handler 的问题是必备的,但是这些关于 Handler 的知识点你都知道吗? 一.题目层次 Handler 的基本原理 子线程中怎么使用 Handler MessageQue ...

  9. wps查找替换使用通配符一个实例

    我现在需要打印一些古诗,很多很多.没有排版. 但发现即使弄个两分栏,还是很不舒服. 于是我就想把古诗之间弄个换行. Ctrl+F  打开查找替换 上框输入  ([0-9])*([0-9])*(.) 下 ...

  10. spring学习07(整合MyBatis)

    10.整合MyBatis 10.1 相关jar包 junit <dependency> <groupId>junit</groupId> <artifactI ...