哦?原来这就是 JVM 垃圾!
大家都知道,JVM 有垃圾回收的机制,垃圾回收的前提是要知道:什么是垃圾!然后再是如何识别垃圾!
什么是垃圾
垃圾,本质上就是没有引用的对象(们),下面来介绍两种垃圾
1. 没有引用指向的对象
下图是对象间引用的状态,从正常引用到引用断开,这个 A 和 C 的引用断开之后,C 就成了那个垃圾。

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 对象,一些常驻的异常对象(比如
NullPointExcepiton、OutOfMemoryError)等,还有系统类加载器。
优点:解决引用计数器所不能解决的循环引用问题。
缺点:
- 耗时:因为需要从
GC Roots开始逐个检查引用; - STW:GC 过程中需要保证对象的引用关系不能发生变化,所以 GC 进行时必须停顿所有执行线程(STW:Stop The World)。
总结
第一部分我们介绍了什么是垃圾:没有任何引用指向的一个或多个对象。
第二部分介绍了如何识别垃圾,有两种算法:
- 引用计数法:通过给对象添加被引用的次数来识别。优点是回收简单及时;缺点是无法解决循环引用。
- 可达性分析法:从一系列根对象(
GC Roots)开始,根据引用关系向下搜索,如果某个对象到GC Roots间没有任何引用,则此对象就是垃圾。优点是解决了循环引用;缺点是耗时和 STW。
哦?原来这就是 JVM 垃圾!的更多相关文章
- JDK分析工具&JVM垃圾回收(转)
转自:http://blog.163.com/itjin45@126/blog/static/10510751320144201519454/ 官方手册:http://docs.oracle.com/ ...
- JVM基础系列第8讲:JVM 垃圾回收机制
在第 6 讲中我们说到 Java 虚拟机的内存结构,提到了这部分的规范其实是由<Java 虚拟机规范>指定的,每个 Java 虚拟机可能都有不同的实现.其实涉及到 Java 虚拟机的内存, ...
- JVM垃圾回收机制与内存回收
暂时转于:https://blog.csdn.net/qq_27035123/article/details/72857739 垃圾回收机制 GC是垃圾回收机制,java中将内存管理交给垃圾回收机制, ...
- 图解JVM垃圾内存回收算法
图解JVM垃圾内存回收算法 这篇文章主要介绍了图解JVM垃圾内存回收算法,由于年轻代堆空间的垃圾回收会很频繁,因此其垃圾回收算法会更加重视回收效率,下面博主和大家来一起学习一下吧 前言 首先,我们要讲 ...
- 深入JVM垃圾回收机制,值得你收藏
JVM可以说是为了Java开发人员屏蔽了很多复杂性,让Java开发的变的更加简单,让开发人员更加关注业务而不必关心底层技术细节,这些复杂性包括内存管理,垃圾回收,跨平台等,今天我们主要看看JVM的垃圾 ...
- .Net平台GC VS JVM垃圾回收
前言 不知道你平时是否关注程序内存使用情况,我是关注的比较少,正好借着优化本地一个程序的空对比了一下.Net平台垃圾回收和jvm垃圾回收,顺便用dotMemory看了程序运行后的内存快照,生成内存快照 ...
- JVM垃圾回收机制总结:调优方法
转载: JVM垃圾回收机制总结:调优方法 JVM 优化经验总结 JVM 垃圾回收器工作原理及使用实例介绍
- JVM 垃圾回收器工作原理及使用实例介绍
IBM介绍文档:https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/ Java 的新生代串行垃圾回收器中使用了复制 ...
- JVM 垃圾回收器工作原理及使用实例介绍(转载自IBM),直接复制粘贴,需要原文戳链接
原文 https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/ 再插一个关于线程和进程上下文,待判断 http://b ...
随机推荐
- Drupal < 7.32 “Drupalgeddon” SQL注入漏洞(CVE-2014-3704)
影响版本Drupal < 7.32
- Python小白的数学建模课-16.最短路径算法
最短路径问题是图论研究中的经典算法问题,用于计算图中一个顶点到另一个顶点的最短路径. 在图论中,最短路径长度与最短路径距离却是不同的概念和问题,经常会被混淆. 求最短路径长度的常用算法是 Dijkst ...
- 教你如何使用FusionInsight SqoopShell
摘要:Sqoop-shell是一个Loader的shell工具,其所有功能都是通过执行脚本"sqoop2-shell"来实现的. 本文分享自华为云社区<FusionInsig ...
- C++ //虚析构和纯虚析构
1 //虚析构和纯虚析构 2 3 #include <iostream> 4 #include <string> 5 using namespace std; 6 7 clas ...
- C++ 结构体+数组+取随机数 案例(打印3名老师 带着 5名学生)结构体
1 //结构体案列 2 3 #include<iostream> 4 #include<string> 5 #include<ctime> 6 using name ...
- Linux下使用pure-ftpd建立匿名ftp访问
by 无若 (一)ubuntu14.04下使用pure-ftpd建立匿名ftp访问 1.安装apt-get install pure-ftpd 2.修改配置nano /etc/pure-ftpd/co ...
- Install and Update autojump and oh-my-zsh Behind a Firewall
Brief installation steps: Install git and zsh via yum; 'git clone' autojump and oh-my-zsh from an in ...
- Spring源码解析之ConfigurationClassPostProcessor(二)
上一个章节,笔者向大家介绍了spring是如何来过滤配置类的,下面我们来看看在过滤出配置类后,spring是如何来解析配置类的.首先过滤出来的配置类会存放在configCandidates列表, 在代 ...
- S3C2440—12.按键中断
文章目录 一. 总体 二. CPSR设置 三. 中断源设置 四. 中断控制器设置 五. C中断处理函数 六. 汇编IRQ异常处理程序 七. 源码 一. 总体 要驱动按键中断控制LED亮灭,程序要进行如 ...
- linux ftp ubuntu18.04 实测有效 完整方法 vsftpd
https://linuxize.com/post/how-to-setup-ftp-server-with-vsftpd-on-ubuntu-18-04/ 除了此链接完整有效,其他网友 大都残缺不全 ...