大家都知道,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。

最新文章

  1. 启用CentOS6.5 64位安装时自带的MySQL数据库服务器
  2. 2016-03-12 Leanning Plan
  3. velocityjs 动画库 比jquery默认的animate强
  4. struts2 的验证框架validation如何返回json数据 以方便ajax交互
  5. 所有Mac用户都需要知道的9个实用终端命令行
  6. 长度有限制的字符串hash函数
  7. fltk demo
  8. 滑轮关节(b2PulleyJoint)
  9. 第一个CGI程序-----完全就是普通的c语言嘛‘(*∩_∩*)′
  10. 安装php的memcached模块和扩展支持sasl
  11. 【汇总目录】Java
  12. 升讯威微信营销系统开发实践:(1)功能概要与架构设计( 完整开源于 Github)
  13. linux:gpg加密和解密
  14. session和cookie的应用场景和区别
  15. js--未来元素
  16. rTorrent + ruTorrent 安装和配置
  17. C语言中的运算和运算符
  18. C语言描述队列的实现及操作(数组实现)
  19. 安装php5.5 mssql扩展报错
  20. python学习-linux基本操作

热门文章

  1. root密码找回
  2. 15 道超经典大厂 Java 面试题!重中之重
  3. Git8.3k星,十万字Android主流开源框架源码解析,必须盘
  4. Longhorn 云原生分布式块存储解决方案设计架构和概念
  5. minio设置永久访问链接
  6. MySQL为什么不支持中文排序?
  7. 安鸾CTF-cookies注入
  8. HTTP和HTTPS是什么 二者区别是什么
  9. QZEZTEST2021.7.27分析
  10. epoll水平/边缘触发模式下阻塞/非阻塞EPOLLOUT事件触发条件及次数