大家都知道,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. IOS自动化测试环境搭建(Python & Java)

         一.前言 IOS的App自动化测试与Android的一样,也可以用appium来进行.但是IOS自动化依赖苹果的osx系统.Xcode构建等,且封闭的系统需要苹果开发者账号才可以驱动真机.A ...

  2. Linux下的Vim文本编辑器(入门)

    引言 vim filename:打开名为filename的文件,如果不存在就会创建一个filename文件 Vim的三种使用模式 1. 命令模式 启动Vim时,就进入了命令模式 在该模式下: i:切换 ...

  3. 跟Waf斗智斗勇的一天

    差点心态爆炸 幸亏整出来了... 最近快放寒假了..临近高考不到最后一星期绝对不学习.. 挖下SRC 这家自带的waf头疼死我了 想几次Fuzz全都撞壁了 然后发现了这家waf的规则 信息搜集不说了 ...

  4. Python3中的字符串相关操作

    Python3的字符串操作相关函数详解 字符串内建函数 1. capitalize() 将字符串中的第一个字符转换成大写,其他字母变成小写.例: >>> "hello Wo ...

  5. SpringBoot | 3.3 整合MyBatis-Plus

    目录 前言 1. 什么是MyBatis-Plus 1.1 BaseMapper接口 1.2 IService接口 2. 整合MyBatis-Plus以及CRUD功能 2.1 导入场景依赖 2.2 CR ...

  6. JVM学习笔记-第三章-垃圾收集器与内存分配策略

    JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...

  7. netty系列之:netty中的懒人编码解码器

    目录 简介 netty中的内置编码器 使用codec要注意的问题 netty内置的基本codec base64 bytes compression json marshalling protobuf ...

  8. 一个tomcat配置多个不同端口的项目

    1.将要同时启动的项目放入不同的webapps文件夹中 2.修改tomcat安装目录下的conf-->setting.xml文件 <?xml version="1.0" ...

  9. Python中用max()筛选出列表中出现次数最多的元素

    1 List = [1,2,3,4,2,3,2] # 随意创建一个只有数字的列表 2 maxTimes = max(List,key=List.count) # maxTimes指列表中出现次数最多的 ...

  10. spring cloud 项目

    ### 项目需求 客户端:针对普通用户,用户登录.用户退出.菜品订购.我的订单. 后台管理系统:针对管理员,管理员登录.管理员退出.添加菜品.查询菜品.修改菜品.删除菜品.订单处理.添加用户.查询用户 ...