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垃圾回收机制.

目录
相关文章
|
22天前
|
存储 算法 Java
先有JVM还是先有垃圾回收器?
是先有垃圾回收器再有JVM呢,还是先有JVM再有垃圾回收器呢?或者是先有垃圾回收再有JVM呢?历史上还真是垃圾回收更早面世,先有垃圾回收再有JVM。下面我们就来刨析刨析JVM的垃圾回收~
37 0
先有JVM还是先有垃圾回收器?
|
3天前
|
存储 算法 Java
【JavaEE初阶】 关于JVM垃圾回收
【JavaEE初阶】 关于JVM垃圾回收
|
7天前
|
存储 算法 Java
深入理解Java虚拟机(JVM)的垃圾回收机制
【5月更文挑战第30天】 在Java开发领域,垃圾回收(Garbage Collection, GC)是确保应用程序性能和内存效率的关键因素。本文将深入探讨Java虚拟机(JVM)的垃圾回收机制,解析其工作原理、不同算法的特点以及如何通过调优来提高应用性能。我们将透过JVM的内存结构,探索垃圾回收过程中涉及的关键技术点,并讨论现代Java应用中常见的垃圾回收器实现。
|
9天前
|
存储 算法 Oracle
深入理解 JVM(重点:双亲委派模型 + 垃圾回收算法)
深入理解 JVM(重点:双亲委派模型 + 垃圾回收算法)
|
13天前
|
存储 算法 Java
JVM(垃圾回收机制 --- GC)
JVM(垃圾回收机制 --- GC)
33 5
|
22天前
|
安全 算法 Java
深入浅出JVM(十三)之垃圾回收算法细节
深入浅出JVM(十三)之垃圾回收算法细节
|
22天前
|
存储 算法 Java
深入浅出JVM(十二)之垃圾回收算法
深入浅出JVM(十二)之垃圾回收算法
|
22天前
|
算法 Java PHP
JVM 的垃圾回收机制以及垃圾回收算法的详解
JVM 的垃圾回收机制以及垃圾回收算法的详解
16 0
|
22天前
|
监控 算法 安全
JVM工作原理与实战(三十九):G1垃圾回收器原理
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了G1垃圾回收器执行流程、年轻代回收原理、卡表(Card Table)、记忆集的生成流程、年轻代回收的详细步骤、混合回收的步骤、初始标记、并发标记、SATB、转移等内容。
48 0
|
22天前
|
存储 监控 算法
JVM工作原理与实战(二十七):堆的垃圾回收-G1垃圾回收器
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了G1垃圾回收器、G1垃圾回收器的回收方式、G1垃圾回收器执行流程、垃圾回收器的选择等内容。
19 0