一.概念

二.核心设计思路

三.如何设定G1对应的内存大小

四.新生代还有Eden和Survivor的概念吗?

五.G1的新生代垃圾回收

六.什么时候触发新生代+老年代的混合垃圾回收?

七.G1垃圾回收的过程

八.回收失败时的Full GC

九.程序假死查验

十. G1参数


一.概念

把Java堆内存拆分为多个大小相等的Region.

G1也会有新生代和老年代的概念,但是只不过是逻辑上的概念.

G1最大的一个特点,就是可以让我们设置一个垃圾回收的预期停顿时间

希望G1在垃圾回收的时候,可以设置由G1垃圾回收导致的“Stop the World”时间,也就是系统停顿的时间. 其实我们对内存合理分配,优化一些参数,就是为了尽可能减少Minor GC和Full GC,尽量减少GC带来的系统停顿,避免影响系统处理请求。 直接可以给G1指定,在一个时间内,垃圾回收导致的系统停顿时间不能超过多久,G1全权给你负责,保证达到这个目标.相当于我们就可以直接控制垃圾回收对系统性能的影响了.

二.核心设计思路

G1可以做到让你来设定垃圾回收对系统的影响,他自己通过把内存拆分为大量小Region,以及追踪每个Region中可以回收的对象大小和预估时间,最后在垃圾回收的时候,尽量把垃圾回收对系统造成的影响控制在你指定的时间范围内,同时在有限的时 间内尽量回收尽可能多的垃圾对象。Region随时会属于新生代也会属于老年代,所以没有所谓新生代给多少内存,老年代给多少内存这一说了.

三.如何设定G1对应的内存大小

默认情况下自动计算和设置的,我们可以给整个堆内存设置一个大小,比如说用“-Xms”和“-Xmx”来设置堆内存的大小。

然后JVM启动的时候一旦发现你使用的是G1垃圾回收器,可以使用“-XX:+UseG1GC”来指定使用G1垃圾回收器,此时会自动用堆大小除以2048

因为JVM最多可以有2048个Region,然后Region的大小必须是2的倍数,比如说1MB、2MB、4MB之类的。

堆大小是4G,那么就是4096MB,此时除以2048个Region,每个Region的大小就是2MB。大概就是这样子来决定Region的数量和大小的,大家一般保持默认的计算方式就可以

手动方式来指定,则是“-XX:G1HeapRegionSize”

默认值:

刚开始的时候,默认新生代对堆内存的占比是5%,也就是占据200MB左右的内存,对应大概是100个Region,这个是可以通  过“-XX:G1NewSizePercent”来设置新生代初始占比的,其实维持这个默认值即可因为在系统运行中,JVM其实会不停的给新生代增加更多的Region,但是最多新生代的占比不会超过60%,可以通过“-XX:G1MaxNewSizePercent”。而且一旦Region进行了垃圾回收,此时新生代的Region数量还会减少,这些其实都是动态的。

四.新生代还有Eden和Survivor的概念吗?

在G1中虽然把内存划分为了很多的 Region,但是其实还是有新生代、老年代的区分.而且新生代里还是有Eden和Survivor的划分的.新生代的参数,“-XX:SurvivorRatio=8”,所以这里还是可以区分出来属于新生代的Region里哪些属于Eden,哪些属于Survivor。比如新生代之前说刚开始初始的时候,有100个Region,那么可能80个Region就是Eden,两个Survivor各自占10个Region.有Eden和Survivor的概念的,他们会各自占据不同的Region。只不过随着对象不停的在新生代里分配,属于新生代的Region会不断增加,Eden和Survivor对应的Region也会不断增加。

五.G1的新生代垃圾回收

随着不停的在新生代的Eden对应的Region中放对象,JVM就会不停的给新生代加入更多的Region,直到新生代占据堆大小的最大比例60%。一旦新生代达到了设定的占据堆内存的最大大小60%,比如都有1200个Region了,里面的Eden可能占据了1000个Region,每个Survivor是100个Region,而且Eden区还占满了对象.这个时候还是会触发新生代的GC,G1就会用之前说过的复制算法来进行垃圾回收,进入一个“Stop the World”状态.然后把Eden对应的Region中的存活对象放入S1对应的Region中,接着回收掉Eden对应的Region中的垃圾对象.但是这个过程跟之前是有区别的,因为G1是可以设定目标GC停顿时间的,也就是G1执行GC的时候最多可以让系统停顿多长时间,
可以通过“-XX:MaxGCPauseMills”参数来设定,默认值是200ms

六.什么时候触发新生代+老年代的混合垃圾回收?

G1有一个参数,是“-XX:InitiatingHeapOccupancyPercent”,他的默认值是45%.

如果老年代占据了堆内存的45%的Region的时候,此时就会尝试触发一个新生代+老年代一起回收的混合回收阶段

七.G1垃圾回收的过程

初始标记 :

首先会触发一个“初始标记”的操作,这个过程是需要进入“Stop the World”的,仅仅只是标记一下GC Roots直接能引用的对象,这个过程速度是很快的。

并发标记:

接着会进入“并发标记”的阶段,这个阶段会允许系统程序的运行,同时进行GC Roots追踪,从GC Roots开始追踪所有的存活对象

这个并发标记阶段还是很耗时的,因为要追踪全部的存活对象。

但是这个阶段是可以跟系统程序并发运行的,所以对系统程序的影响不太大。

而且JVM会对并发标记阶段对对象做出的一些修改记录起来,比如说哪个对象被新建了,哪个对象失去了引用。

最终标记阶段:

这个阶段会进入“Stop the World”,系统程序是禁止运行的,

但是会根据并发标记 阶段记录的那些对象修改,最终标记一下有哪些存活对象,有哪些是垃圾对象

混合回收:

最后一个阶段,就是“混合回收“阶段,这个阶段会计算老年代中每个Region中的存活对象数量,存活对象的占比,还有执行垃圾回收的预期性能和效率。接着会停止系统程序,然后全力以赴尽快进行垃圾回收,此时会选择部分Region进行回收,因为必须让垃圾回收的停顿时间控制在我们指定的范围内。

比如说老年代此时有1000个Region都满了,但是因为根据预定目标,本次垃圾回收可能只能停顿200毫秒,那么通过之前的计算得知,可能回收其中800个Region刚好需要200ms,那么就只会回收800个Region,把GC导致的停顿时间控制在我们指定的范围内

其实老年代对堆内存占比达到45%的时候,触发的是“混合回收.也就是说,此时垃圾回收不仅仅是回收老年代,还会回收新生代,还会回收大对象.

到底是回收这些区域的哪些Region呢?

那就要看情况了,因为我们设定了对GC停顿时间的目标,所以说他会从新生代、老年代、大对象里各自挑选一些Region,
保证用指定的时间(比如200ms)回收尽可能多的垃圾,这就是所谓的混合回收

八.回收失败时的Full GC

如果在进行Mixed回收的时候,无论是年轻代还是老年代都基于复制算法进行回收,都要把各个Region的存活对象拷贝到别的Region去

此时万一出现拷贝的过程中发现没有空闲Region可以承载自己的存活对象了,就会触发 一次失败

一旦失败,立马就会切换为停止系统程序,然后采用单线程进行标记、清理和压缩整理,空闲出来一批Region,这个过程是极慢极慢的

九.程序假死查验

先用top查看一下机器负载

1.使用了大量内存,并且内存无法释放,导致GC:

(1). 内存使用率高,导致频繁full gc, gc带来的STW影响业务

(2).内存使用率过多.导致JVM发生OOM

(3).内存使用率过高,也许有的时候,导致这个进程因为申请内存不足,直接被操作系统把这个进程杀掉了

2.机器CPU负载过高,也许是某个进程耗尽CPU,导致你的服务线程无法获取到cpu资源

十. G1参数

-XX:G1MixedGCCountTarget

一般在老年代的Region占据了堆内存的Region的45%之后,会触发一个混合回收的过程,也就是Mixed GC.

在这里最后一个环节,其实就是执行混合回收,从新生代和老年代里都回收一些Region。但是最后一个阶段混合回收的时候,其实会停止所有程序运行,所以说G1是允许执行多次混合回收比如先停止工作,执行一次混合回收回收掉 一些Region,接着恢复系统运行,然后再次停止系统运行,再执行一次混合回收回收掉一些Region。有一些参数可以控制这个,比如“-XX:G1MixedGCCountTarget”参数,就是在一次混合回收的过程中,最后一个阶段执行几次混合回收,默认值是8次.意味着最后一个阶段,先停止系统运行,混合回收一些Region,再恢复系统运行,接着再次禁止系统运行,混合回收一些Region,反复8次.

假设一次混合回收预期要回收掉一共有160个Region,那么此时第一次混合回收,会回收掉一些Region,比如就是 20个Region(年轻代10个,老年代10个)。接着恢复系统运行一会儿,然后再执行一次“混合回收”(年轻代10个,老年代10个)如此反复执行8次混合回收阶段之后 ,不就把预订的160个Region都回收掉了?而且还把系统停顿时间控制在指定范围内。

那么为什么要反复回收多次呢?

因为你停止系统一会儿,回收掉一些Region,再让系统运行一会儿,然后再次停止系统一会儿,再次回收掉一些Region,这样可以尽
可能让系统不要停顿时间过长,可以在多次回收的间隙,也运行一下

-XX:G1HeapWastePercent

“-XX:G1HeapWastePercent”,默认值是5%

在混合回收的时候,对Region回收都是基于复制算法进行的,都是把要回收的Region里的存活对象放入其他Region,然后这个Region中的垃圾对象全部清理掉.这样的话在回收过程就会不断空出来新的Region,一旦空闲出来的Region数量达到了堆内存的5%,此时就会 立即停止混合回收,意味着本次混合回收就结束了。而且从这里也能看出来G1整体是基于复制算法进行Region垃圾回收的,不会出现内存碎片的问题,不需要像CMS那样标记-清理之后,再进行内存碎片的整理。

-XX:G1MixedGCLiveThresholdPercent

默认值是85%

确定要回收的Region的时候,必须是存活对象低于85%的Region才可以进行回收

如果把85%的对象都拷贝到别的Region,这个成本是很高的。

[JVM]了断局: G1 入门相关推荐

  1. [JVM]了断局: [ 目录 ]

    [JVM]了断局: 说什么也没用,背就完了[必背] [JVM]了断局: "运行时数据区"理论梳理 [JVM]了断局: 虚拟机字节码指令表速查 [JVM]了断局: 类文件结构梳理 [ ...

  2. [JVM]了断局: 局部变量表和操作数栈实例分析

    一.前言 本文以两段代码示例来解释说明,JVM在执行类中的方法时,[局部变量表]和[操作数栈]是如何配合工作的. 示例一: 1.代码 package com.classloading;public c ...

  3. [JVM]了断局: Class文件结构梳理

    预警: 这是一篇枯燥的文章,然而还是得懂. 慢慢看,头疼了就出去溜溜..... Table of Contents 一.概念 二. 示例代码 三.魔数 四.版本号 五. 常量池 六.访问标志 七.类索 ...

  4. [JVM]了断局: “运行时数据区“理论梳理

    Table of Contents 一.前言 二.运行时数据区 2.1.程序计数器 2.2.Java堆 2.3.方法区 2.4.运行时常量池 2.5.直接内存 2.6.Java虚拟机栈 2.7.本地方 ...

  5. [JVM]了断局: 说什么也没用,背就完了[必背]

    Table of Contents 一. JVM在什么情况下会加载一个类 二. 什么时候会初始化一个类 ? 三.类加载器 四.什么情况下JVM内存中的一个对象会被垃圾回收?? 五.如何进入老年代 六. ...

  6. [JVM]了断局: 堆外内存无法 [ -XX:MaxDirectMemorySize ] 限制

    一. 前言 今天看到一句话 , 有点懵, 所以验证一下. 使用sun.misc.Unsafe的allocateMemory方法分配堆外内存.不受-XX:MaxDirectMemorySize这个JVM ...

  7. [JVM]了断局:字节码执行引擎

    Table of Contents 一.前言 二.运行时栈帧结构 1.局部变量表 2.操作数栈 3.动态连接 4.方法返回地址 5.附加信息 三.方法调用 1.方法调用 2.解析 一.前言 执行引擎是 ...

  8. [JVM]了断局:常量池 VS 运行时常量池 VS 字符串常量池

    一.前言 最近在看JVM, 常量池, 运行时常量池,字符串常量池 这个看的有点懵. 整理一下. class常量池 是在编译的时候每个class都有的. 在编译阶段,存放的是常量的 符号引用 .    ...

  9. [JVM]了断局:内存模型与线程

    一.前言 Java内存模型的主要目的是定义程序中各种变量的访问规则, 即关注在虚拟机中把变量值存储到内存和从内存中取出变量值这样的底层细节. Java内存模型规定了所有的变量都存储在主内存(Main ...

最新文章

  1. char[]和char*的区别(转)
  2. 004-React入门概述
  3. play框架入门操作
  4. 【软件测试】黑盒测试の因果图法
  5. 各行各业有对象系列之三:对象存储与银行
  6. How To Search and Restore files from Site Collection Recycle Bin
  7. 2020 快手 被吊打面经
  8. 美国新泽西州,也有一个Menlo Park——门洛公园,尽管不太为人熟知,但爱迪生那里的一个发明却点亮了全世界。...
  9. sql server 2008 新建服务器注册,SQL Server 2008中不能注册服务器怎么回事
  10. 论合伙企业相对有限责任公司的比较优势
  11. 求一段看不懂的乱码_这些真的不是乱码,是汉字!竟然一个都不认识
  12. 自定义fingerprint特征
  13. 上海市提取公积金攻略
  14. 50行的python游戏代码_教你使用50行Python代码刷王者荣耀金币
  15. xp系统和win7系统哪个好
  16. [IMX6Q]u-boot_v2009.08编译过程
  17. 【演讲实录+视频】走近40+世界级AI专家!第三届中国人工智能大会资料分享(直播进行中_不断更新)
  18. vue scoped html样式无效
  19. 《阿里云天池大赛赛题解析(深度学习篇)》学习笔记(3)实体识别深度学习方法
  20. 苹果XS怎么截屏_可怜的果粉,安卓有这功能快十年之后,苹果发布竟让果粉一片欢呼...

热门文章

  1. oracle heavy swapping,WARNING: Heavy swapping observed on system in last 5 mins
  2. OSChina 周三乱弹 —— 围观单片机大佬
  3. 我在大厂写React学到了什么?性能优化篇
  4. mysql开发二手书籍交易_基于PHP+MySQL二手书交易系统
  5. android离线语音开发,Android应用开发之Android 云之声离线语音合成
  6. 20200928 006.简单错误如何处理_守破离学习法_程序员修炼手册
  7. 关于策略优化的一些简单想法
  8. 瑞幸咖啡布局“无人零售”的多重不确定性
  9. 计算机多媒体论文摘要,急需一篇计算机多媒体论文
  10. 求华摄氏度100‘F对应下的摄氏温度