性能文章>「每日五分钟,玩转JVM」:两种算法>

「每日五分钟,玩转JVM」:两种算法原创

694401

前言

上篇文章,我们了解了GC 的相关概念,这篇文章我们通过两个算法来了解如何去确定堆中的对象实例哪些是我们需要去回收的垃圾对象。

引用计数算法

image.png
引用计数法的原理很简单,就是在对象中维护一个计数器,当有一个对象引用它的时候,该计数器的值就会加一,当这个引用失效的时候,计数器的值就会减少一,当计数器的值为零的时候,就意味着这个对象是一个垃圾对象,需要被 GC 回收,这个算法是一个比较高效的算法,但是会存在一种对象循环引用导致内存泄露的问题,什么是循环引用呢?

image.png
就像这样,对象 A 和对象 B 之间存在相互引用,但是除此之外,这两个对象再无引用,讲道理,这两个对象是属于我们定义的垃圾中的,但是由于计数器的值不为零,所以就无法被标记为垃圾,我们的 GC 也就无法去回收这两个对象,这两个对象会失去控制,长久的存在我们的对象中占用内存,造成内存的泄露。

可达性分析法

这个算法我一般理解为落叶归根算法(

),为什么这么说呢?这个算法的原理也很简单,就是维护一系列的『GC ROOT』的对象作为我们的根,从这些根搜索,走过的路径官方话叫做引用链(Reference Chain),当一个对象到根节点没有任何引用,就意味着这个对象是不可用的,也就是我们俗称的垃圾~

换个说法来理解很简单:长在树上的叶子是我们的可用对象,当叶子脱离了树枝,与树根之间没有任何联系的时候,就需要落叶归根,被 GC 回收,也就是落红不是无情物,化作春泥更护花~
image.png
那么在我们的 JVM 中,可以被认为是 GC ROOTS 的对象有以下几种:

  • 虚拟机栈中引用的对象

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

  • 方法区中常量引用的对象

  • 本地方法栈中 JNI(Java Native Interface) 引用的对象

后记

最近笔者在更新自己的 GTD 系统,说来惭愧,玩了一年了才算是有所领悟,年前会出一篇超长的 GTD 的个人经验和实践过程中遇到的问题,从工具到遇到的问题都会有,敬请期待~

请先登录,再评论

暂无回复,快来写下第一个回复吧~

为你推荐

不起眼,但是足以让你有收获的JVM内存分析案例
分析 这个问题说白了,就是说有些int[]对象不知道是哪里来的,于是我拿他的例子跑了跑,好像还真有这么回事。点该 dump 文件详情,查看相关的 int[] 数组,点该对象的“被引用对象”,发现所
从一起GC血案谈到反射原理
前言 首先回答一下提问者的问题。这主要是由于存在大量反射而产生的临时类加载器和 ASM 临时生成的类,这些类会被保留在 Metaspace,一旦 Metaspace 即将满的时候,就会触发 Fu
关于内存溢出,咱再聊点有意思的?
概述 上篇文章讲了JVM在GC上的一个设计缺陷,揪出一个导致GC慢慢变长的JVM设计缺陷,可能有不少人还是没怎么看明白的,今天准备讲的大家应该都很容易看明白 本文其实很犹豫写不写,因为感觉没有
协助美团kafka团队定位到的一个JVM Crash问题
概述 有挺长一段时间没写技术文章了,正好这两天美团kafka团队有位小伙伴加了我微信,然后咨询了一个JVM crash的问题,大家对crash的问题都比较无奈,因为没有现场,信息量不多,碰到这类问题我
又发现一个导致JVM物理内存消耗大的Bug(已提交Patch)
概述 最近我们公司在帮一个客户查一个JVM的问题(JDK1.8.0_191-b12),发现一个系统老是被OS Kill掉,是内存泄露导致的。在查的过程中,阴差阳错地发现了JVM另外的一个Bug。这个B
JVM实战:优化我的IDEA GC
IDEA是个好东西,可以说是地球上最好的Java开发工具,但是偶尔也会卡顿,仔细想想IDEA也是Java开发的,会不会和GC有关,于是就有了接下来对IDEA的GC进行调优 IDEA默认JVM参数: -
不起眼,但是足以让你收获的JVM内存案例
今天的这个案例我觉得应该会让你涨姿势吧,不管你对JVM有多熟悉,看到这篇文章,应该还是会有点小惊讶的,不过我觉得这个案例我分享出来,是想表达不管多么奇怪的现象请一定要追究下去,会让你慢慢变得强大起来,
如何通过反射获得方法的真实参数名(以及扩展研究)
前段时间,在做一个小的工程时,遇到了需要通过反射获得方法真实参数名的场景,在这里我遇到了一些小小的问题,后来在部门老大的指导下,我解决了这个问题。通过解决这个问题,附带着我了解到了很多新的知识,我觉得