JVM垃圾回收

简介: 如题分享一些关于JVM相关的概念理论

JVM垃圾回收机制


GC的基础知识


什么是垃圾?


垃圾一般指的是在程序中占用空间,但是没有丝毫意义和引用对象的简称.


image.png


垃圾回收器的作用?


有垃圾回收器的语言:开发效率较高. 帮助我们自动回收垃圾,减少代码量,并且减少系统出错概率.


代表语言: Java.Go.Python.


没有垃圾回收器的语言:运行效率较高.可能会出现重复回收或者说的忘记回收.


代表语言:C.C++.


从大局观上来讲,一般最新的语言都会配置垃圾回收器,因为这样可以大大提高我们的开发效率,随着现在互联网框架体系的趋势,人们对开发效率可以说的越来越注重,而不是特别注重其中的运行效率,毕竟把HelloWord拿过来举例子,以前汇编语言可能要写100行,而现在Java只需要几行就可以实现了.


垃圾定位算法


reference count(引用计数)


image.png


作用:当数字指向0的时候,默认进行垃圾回收.


因为实现较为简单,也是目前很多语言的首选垃圾定位算法,比如说Python.


缺点:无法解决循环引用的问题,可能会出现一堆垃圾互相引用的问题.


image.png


root searching(根可达算法)


image.png


作用:从根出发,只要是能触及到根部的,那么就都不算垃圾,反之只要我触碰不到的,那一定就是垃圾。


在Java中使用的就是根可达算法,因为Java既想要保证开发效率,又想要保证一定的运行效率.


垃圾回收算法


Mark-Sweep(标记清除)


和扫雷那款游戏很像,标记垃圾,然后最后会进行一个清除.


优点:在垃圾回收算法中相对来说比较简单.


缺点:清除之后空间不是连续性的,中间多了很多缝隙.


image.png


Mark-Compact(标记压缩)


和算法中的指针排序很类似,把有用到符合规定的数字全部排列到数组的最前面,然后对后面的所有索引进行一个清空.


image.png


缺点:效率低,要一边标记,一边进行压缩.


Copying(拷贝)


只允许使用一半空间,当那一半的空间快满的时候,使用根可达算法拿出所有需要用到的,然后按规律排列好,隔绝了标记清除算法中空间的断续出现问题,把另外一半空间整体性的擦除掉,这个效率是非常高的,如果知道内存原理的话,我们会知道只需要一个起始地址和一个内存的长度,就能进行一个内存擦除,这个效率是很高的.


image.png


缺点:空间上的浪费,是一种空间换时间的机制.


垃圾回收算法总结


Mark-Sweep(标记清除算法)


优点:算法简单,容易实现.


缺点:碎片化,空间是断续的.


Mark-Compact(标记压缩)


优点:没有空间的碎片化,空间利用率也比Copying算法来的高.


缺点效率比较低,算法较难实现.


Colpying(拷贝)


优点:效率高,并且不会有空间的碎片化问题.


缺点:空间利用率只有2分之一,是用空间换时间在垃圾回收算法当中的一种具体体现.


JVM模型


JDK1.8和在这之前使用的是分代模型,有两大块区域.


JDK1.9之后是分区模型,并且是付费的,所以使用人数较少,把本身的内存比喻成大房子的话,分区模型就相当于分成一个个的小房间.


image.png


垃圾回收过程


image.png


新生代和老年代比例默认是1比2的关系,这个比例是可以调整的,通过JVM调优.


年轻代:默认比例为8:1:1


伊甸园区到->幸存者区


首先假设伊甸园区中有10个对象,其中最后幸存下来了一个对象,他会被拷贝到幸存者区中,这个幸存者区域设计就不需要特别大了,大概前面的10分之一左右就行,可以把剩余的空间余给伊甸园区,然后在伊甸园区执行一次gc,直接进行一个内存擦除,这个效率是非常高的.


幸存者区左->幸存者区右


幸存者区左满了之后把有用的对象放到幸存者区(右),并且和伊甸园区一起进行一次内存擦除.


幸存者区右->幸幸存者区左


幸存者区右满了之后把有用的对象放到幸存者区(左),并且和伊甸园区一起进行一次内存擦除.


不对等复制算法.


连续15次之后,把剩余的数据放入老年代当中.(这个次数也是可以设置的)


对象太大会直接进入老年代,如果老年代都装不下,那么就会直接OOM.


`


存活次数和什么有关?


markwork对象头中可以进行设置,也跟算法有关系.默认是15.比如CMS算法默认6次就进入老年代了..(这个次数也是可以设置的)


垃圾收集器


前置知识


stop the world


停止所有线程,当我们的业务停止的时候,对于我们用户来讲就是没有反应了,所以有时候我们运行一小段就会卡一小段,尤其是内存不足的时候.


在新生代进行的GC叫做minor GC,在老年代进行的GC都叫major GC,Full GC同时作用于新生代和老年代。在垃圾回收过程中经常涉及到对对象的挪动(比如上文提到的对象在Survivor 0和Survivor 1之间的复制),进而导致需要对对象引用进行更新。为了保证引用更新的正确性,Java将暂停所有其他的线程,这种情况被称为“Stop-The-World”,导致系统全局停顿。Stop-The-World对系统性能存在影响,因此垃圾回收的一个原则是尽量减少“Stop-The-World”的时间。


这里会有一个问题,如果内存小的话,我们执行一次stop the world可能只是会停顿毫秒,但是当内存大了的时候,可能是秒甚至上百秒了.



有时候其实所谓的JVM调优就是把停顿的时间给缩短,在用户访问的时候给与用户及时的反馈,而不是一次停顿10几秒.



三色标记算法


golong使用的也是三色标记算法.


黑白灰三色.


黑:自己标记完成了,孩子也已经标记完成.


灰:自己标记完成了,还没有来得及标记孩子. 比如学生类中的name就是它的孩子.


白:没有找到的节点.


和选飞机座位一样,黑色是已经选择的,灰色是可选的,白色就是不能选择的,比如买的商务舱就不能选择头等和经济舱.


image.png


Serial


清理年轻代的垃圾,是单线程的,到现在已经不常用了.


Serial Old


清理老年代的垃圾,和Serial一样,到现在已经不常用了.


image.png


Parallel Scavenge


利用多线程清理年轻代的垃圾.


Parallel Old


利用多线程清理老年代的垃圾.



但是注意线程也不是越多越好的,如果当我们的内存到达一定的大小之后,再使用多线程就会将时间浪费在频繁切换的时间上,在那种情况下多线程也会满足不了我们的需求了.




ParNew


CMS(并发标记算法)


垃圾回收线程工作一小段,业务线程工作一小段,每个人都只工作一小段,然后连续的运行,才能够完全定位整个内存当中的垃圾.


比如在内存当中,垃圾回收线程先运行首先找到了A对象,这时候打个标记在上面,在我执行业务线程之后又轮到了垃圾回收线程第二次执行,他会从之前打标记的A对象位置开始执行,然后断断续续的执行.


那么如果中途对象变成垃圾了怎么办,或者垃圾又有引用了该怎么办.


中途变成垃圾一般称之为浮动垃圾,大不了下载垃圾gc的时候再次进行清除,这也是CMS百分之92的时候就会进行full GC的原因.



CMS解决方案(增量更新)


情况:


B->D消失


A->D增加


垃圾重新被引用也是一种比较麻烦的情况,默认从B开始找,本来B下面是D,结果现在为null了,就会默认D是垃圾,但是实际上D被A所关联了,他并不是垃圾.


image.png


以后调用A.D就可能直接出现空指针异常了,这时候我们如果把A的颜色变成灰色,之后垃圾回收线程还会去访问它的子类,做出新的标记就可以避免空指针异常.


image.png


CMS增量更新漏标问题


image.png


增量更新算法是有BUG的,CMS本身其实还不是一个特别成熟的垃圾回收器,需要高超的调优技术才能将它进行调优,默认的解决方案是重新从头扫描一遍,有时候用了CMS可能卡顿会更加严重,你不仅内存大,最后甚至还要重新在扫描一遍,STW的现象依然会非常严重.


建议出现BUG之后,直接改为G1垃圾回收机制.

目录
相关文章
|
5月前
|
存储 算法 Oracle
极致八股文之JVM垃圾回收器G1&ZGC详解
本文作者分享了一些垃圾回收器的执行过程,希望给大家参考。
|
2月前
|
监控 算法 Java
Java虚拟机(JVM)的垃圾回收机制深度解析####
本文深入探讨了Java虚拟机(JVM)的垃圾回收机制,旨在揭示其背后的工作原理与优化策略。我们将从垃圾回收的基本概念入手,逐步剖析标记-清除、复制算法、标记-整理等主流垃圾回收算法的原理与实现细节。通过对比不同算法的优缺点及适用场景,为开发者提供优化Java应用性能与内存管理的实践指南。 ####
|
1月前
|
监控 算法 Java
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
40 0
|
11天前
|
算法 网络协议 Java
【JVM】——GC垃圾回收机制(图解通俗易懂)
GC垃圾回收,标识出垃圾(计数机制、可达性分析)内存释放机制(标记清除、复制算法、标记整理、分代回收)
|
1月前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
2月前
|
机器学习/深度学习 监控 算法
Java虚拟机(JVM)的垃圾回收机制深度剖析####
本文深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法、性能调优策略及未来趋势。通过实例解析,为开发者提供优化Java应用性能的思路与方法。 ####
54 1
|
2月前
|
监控 算法 Java
Java虚拟机垃圾回收机制深度剖析与优化策略####
【10月更文挑战第21天】 本文旨在深入探讨Java虚拟机(JVM)中的垃圾回收机制,揭示其工作原理、常见算法及参数调优技巧。通过案例分析,展示如何根据应用特性调整GC策略,以提升Java应用的性能和稳定性,为开发者提供实战中的优化指南。 ####
47 5
|
2月前
|
存储 算法 安全
JVM常见面试题(四):垃圾回收
堆区域划分,对象什么时候可以被垃圾器回收,如何定位垃圾——引用计数法、可达性分析算法,JVM垃圾回收算法——标记清除算法、标记整理算法、复制算法、分代回收算法;JVM垃圾回收器——串行、并行、CMS垃圾回收器、G1垃圾回收器;强引用、软引用、弱引用、虚引用
|
2月前
|
存储 算法 Java
JVM进阶调优系列(10)敢向stop the world喊卡的G1垃圾回收器 | 有必要讲透
本文详细介绍了G1垃圾回收器的背景、核心原理及其回收过程。G1,即Garbage First,旨在通过将堆内存划分为多个Region来实现低延时的垃圾回收,每个Region可以根据其垃圾回收的价值被优先回收。文章还探讨了G1的Young GC、Mixed GC以及Full GC的具体流程,并列出了G1回收器的核心参数配置,帮助读者更好地理解和优化G1的使用。
|
2月前
|
监控 Java 测试技术
Elasticsearch集群JVM调优垃圾回收器的选择
Elasticsearch集群JVM调优垃圾回收器的选择
59 1