了解JVM中的GC
Posted XeonYu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了了解JVM中的GC相关的知识,希望对你有一定的参考价值。
上一篇:
了解 JVM和JVM内存结构(JVM运行时数据区)
上一篇博客我们对JVM的内存结构有了一个简单的认识,我们都知道Java是有GC自动对内存进行回收的,那GC到底是怎么工作的,对象在什么时候会被回收呢?
本篇博客我们就来了解一下GC;
GC
Garbage Collector :垃圾收集器
顾名思义,就是专门收集垃圾的。
什么是垃圾
简单来讲,没有任何引用指向的对象(没有任何用处的对象),就是垃圾,要被回收掉。
怎么判断一个对象是不是垃圾
引用计数器法
简单将就是一个对象每被另一个对象所引用,则计数器+1,解除引用后-1,如果一个对象的引用计数器为0,则视为垃圾。
根可达性分析法
根:又叫做 GC roots
先来看看JVM内存模型中哪些属于GC roots
- 虚拟机栈
- 本地方法
- 常量池
- 方法区中的静态变量等
通过GC roots 根节点一直往下找,能找到的引用的对象都不是垃圾,其他的就都是垃圾。
如图所示:
其中,蓝色的就会被标记为非垃圾对象。其它的自然而然就是垃圾对象了。
常见的垃圾回收算法
标记清除法
先对内存扫描一遍,将是垃圾对象所在的区域标记一下,然后进行回收。
缺点:会产生不连续的空间
图示如下
拷贝清除法
将内存一分为二,只用一半的空间存放对象,当前使用的一半空间需要做内存回收时,先对这一半的空间进行扫描,将不是垃圾的对象拷贝到另一半空间,然后对现在这一半的空间整体进行回收。
当另一半满了需要做内存回收时,则再走一遍上述过程,将不需要回收的对象拷贝到这一半,然后直接回收掉另一半空间。
周而复始。
图示如下:
优点:不会产生内存碎片
缺点:浪费空间
标记压缩法:
在扫描的时候,将标记为垃圾的区域进行回收,然后把存活的对象挪到当前区域,同时遇到未使用的空间时,如果后面还有存活对象,则也挪到当前可使用区域。
图示如下:
优点:不会产生内存碎片
缺点:效率相对较低
JVM 分代模型
了解完常见的回收算法后,我们来看一下JVM的分代模型
以 JDK1.8 默认垃圾回收器为例
JVM 将堆内存分为两代,年轻代和老年代。
默认情况下,年轻代占堆大小的三分之一,老年代占堆大小的三分之二
如图所示
年轻代中又分为伊甸区和幸存者区,其中幸存者区又分为S0和S1区。伊甸区占年轻代大小的8/10,S0和S1分别占1/10
其中,新生代中的回收算法使用的是 拷贝清除法 ,老年代中的回收算法是标记压缩法
我们来看一下一个对象从产生到被回收大概的过程是怎样的
先看一下新创建的对象是如何存放到堆中的,如图所示
full gc: 整个堆的gc(包含年轻代和老年代),由于使用的是标记压缩法,效率较低,代价较大
minor gc: 也叫young gc:对年轻代进行gc,默认使用复制清除法,效率高
总结:新创建的对象会先往伊甸区中存放,绝大多数情况下都能放下,除非对象特别大且伊甸区放不下,会先对伊甸区进行一次minor gc,gc过后如果伊甸区能放下,放入伊甸区,还是放不下的话,则会尝试向老年代中存放,如果老年代也放不下,则会先进一次full gc, 回收过后如果老年代空间足够,放入老年代,老年代也放不下的话,报OOM异常。
再来看下GC的过程中是怎么处理对象的
当伊甸区容量达到一定的条件或者JVM虚拟机空闲时,会触发minor gc
首次回收时:会先使用 根可达性分析法 标记伊甸区中的非垃圾对象,然后将这些对象复制到S0区域,然后将整个伊甸区全部回收。
再次回收:先使用 根可达性分析法 找出伊甸区和S0区中非垃圾对象,将这些对象复制到S1区,然后直接将伊甸区和S0区全部回收
再次回收:先使用 根可达性分析法 找出伊甸区和S1区中非垃圾对象,将这些对象复制到S0区,然后直接将伊甸区和S1区全部回收
周而复始…
大致上就是使用上面的拷贝清除法来回收年轻代中的内存。需要注意的是,如果一个对象经历过15次(默认值是15)minor gc还没有被回收掉,就会将该对象移至老年代
老年代的回收就是上面的标记压缩法了,需要注意的是,当老年代没有足够的内存存放数据时,会先进行一次full gc,full gc之后如果仍然没有足够的空间存放对象,则会报出OOM异常。
一般Java开发工程师所说的JVM调优,实际上就是通过修改一些参数,以达到尽可能的减少full gc的次数的目的。
好了,到这里,我们对JVM内存回收算是有了一个基本的认识了。
如果你觉得本文对你有帮助,麻烦动动手指顶一下,可以帮助到更多的开发者,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!
以上是关于了解JVM中的GC的主要内容,如果未能解决你的问题,请参考以下文章