IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【JVM】垃圾回收机制,真通俗易懂 -> 正文阅读

[Java知识库]【JVM】垃圾回收机制,真通俗易懂

堆内存的划分

分为三个部分(以下名词表示同一个区):

  • 新生区、新生代、年轻代
  • 养老区、老年区、老年代
  • 永久区、永久代
    在这里插入图片描述

划分区域的目的

唯一目的就是优化GC性能。

如果没有分代,我们所有的对象都放在一块,GC的时候我们需要对堆的所有区域进行扫描。而很多的对象都是“朝生夕死”的,如果把创建的新的对象都放在某一地方,当GC的时候就先把“朝生夕死”对象的区域进行回收,这样就会腾出很多大的空间来。

一、新生区的垃圾回收机制

新生区分为:Eden区、Survivor0区、Survivor1区(也称为from区和to区)
其中Eden区占80%的内存空间,每块Survivor各占用10%的内存空间(如:Eden占800M,每个Survivor占100M)

  1. 开始时创建的对象都是分配在Eden区域中,当Eden区快满了,就会触发垃圾回收Minor GC(使用复制算法进行垃圾回收)
    在这里插入图片描述
  2. Minor GC处理后,首先会把Eden区中还存活着的对象一次性转入其中一块空闲着的Survivor区。然后清空Eden区,之后创建的对象就继续放入Eden区中了,直至下次Eden又被填满。
    在这里插入图片描述
  3. Eden再次被填满时,就会再次出发Minor GC,清理后(Minor会清理Eden区和Survivor区的内存),Eden区和存在对象的Survivor区(此时的from区)中存活的对象转移到另一块空着的Survivor区中(此时的to区),并清空Eden区和之前存在对象的Survivor区(此时变为to区了,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。)

这就是复制算法的流程。
一直要保持一个Survivor区是空的以提供复制算法垃圾回收,而这块区域的内存只占整块的10%,其他90%内存都可以被使用,课件内存利用率还是相当高的。

二、什么时候进入老年区呢?

1 经历15次GC后进入老年区

默认情况下,如果新生区中的某个对象经历了15次GC后,还是没有被回收掉,那么它就会被转入老年区。
可通过JVM参数“-XX:MaxTenuringThreshold”来设置,默认是15。

2 动态对象年龄判断

这种方法不用等到经历GC15次。
假如一批对象总大小大于当前Survivor区内存的50%,那么大于等于这批对象年龄的对象就会被转移到老年区。

例:假设Survivor0区中的两个对象都经历的3次GC(年龄3),而且这两个对象总大小50M,超过了Survivor0区内存大小的一半。那么此时Survivor0区中年龄大于等于3岁的对象就都要被全部转移到老年区。
在这里插入图片描述

3 大对象直接进入老年代

有一个JVM参数"-XX:PretenureSizeThreshold",默认值是0,表示任何情况都先把对象分配给Eden区。
若设置为1048576字节,也就是1M。则表示当创建的对象大于1M时,就会直接把这个对象放入到老年区,就根本不会经过新生区了。
这么做的原因:大对象在经历复制算法进行GC的时候会降低性能。

4 Minor GC后存活的对象太多无法放入Survivor区了

Minor GC后存活的对象太多,导致Survivor区放不下了,此时就会将所有的对象直接转移到老年区中。

三、老年区空间分配担保原则

执行每一次Minor GC前,JVM都先检查一下老年区可用的内存空间是否大于新生区所有对象的总大小。
原因:极端情况下,Minor GC后,新生代中所有的对象都活了下来,那就会把所有新生代中的对象放入老年区中。

  • 如果说老年区可用内存大于新生代对象总大小,那么就可以放心的执行Minor GC。
  • 但如果老年区内存小于新生区对象的总大小,这时候就会看一个参数:“-XX:HandlePromotionFailure”是否设置为true了。
    如果为true,就进入下一次判断,看老年区可用内存是否大于之前每次Minor GC后进入老年区对象的平均大小。如果老年代可用内存小于平均大小或是参数没有设置成true,那就会直接触发“Full GC”,就是对老年代进行垃圾回收,腾出空间后,再进行Minor GC,相当于对新生区、老年区统一做了一次清理。

三种情况递进理解:

  1. 如果Minor GC后,存活的对象<Survivor区大小,直接进入Survivor区即可;
  2. 如果Minor GC后,存活的对象>Survivor区大小,但<老年区可用内存,直接进入老年区;
  3. 若Minor GC后,此时老年区都放不下这些存活的对象了,就会触发Full GC;
    如果Full GC后老年区内存还是不够用,就会导致OOM内存溢出。

四、老年区垃圾回收算法

标记整理算法

【原理】
一开始对象都是任意分布的,在经历完垃圾回收之后,就会标记出哪些是存活对象,哪些是垃圾对象,然后就会把这些存活的对象在内存中进行整理移动,尽量都挪到一边去靠在一起,然后再把垃圾对象进行清除,这样做的好处就是避免了垃圾回收后产生的大片内存碎片。
在这里插入图片描述

【缺点】
较为耗时,比复制算法慢10倍;
所以如果系统频繁出现Full GC,会严重影响系统性能,出现卡顿。所以JVM优化的一大问题就是减少Full GC频率。

五、垃圾回收器

新生区和老年区进行垃圾回收时是通过不同的垃圾回收器进行回收的
Seral 和 Seral Old垃圾回收器

  • 分别用于回收新生区和老年区。
  • 单线程运行,垃圾回收时会停止我们系统的其他线程,再执行垃圾回收(不再使用);

ParNew和CMS垃圾回收器

  • 分别用于新生区和老年区;
  • 多线程并发,性能更好,现在一般是线上生产系统的标配。

G1垃圾回收器

  • 统一收集新生区和老年区,采用更加优秀的算法机制。
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 11:16:56  更:2022-02-26 11:21:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:21:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码