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知识库 -> g1gc调优的一次实战记录 -> 正文阅读

[Java知识库]g1gc调优的一次实战记录

Java内存区域 或 Jvm 内存结构

JVM内存区域
线程共享

  • 方法区
  • 直接内存
  • (非运行时数据区的一部分)
    线程私有
  • 程序计数器
  • 虚拟机栈
  • 本地方法栈
    JDK 8 版本之后方法区(HotSpot 的永久代)被彻底移除了(JDK1.7 就已经开始了),取而代之是元空间

GC算法

  • 1,标记 -清除算法
  • 2,复制算法
  • 3,标记-压缩算法
  • 4,分代收集算法
    一般将堆分为新生代和老年代。
    新生代使用: 复制算法
    老年代使用: 标记 - 清除 或者 标记 - 整理 算法

G1 GC

  • G1 GC是Java HotSpot虚拟机的低暂停服务器风格分代垃圾收集器,适用于具有大内存的多处理器计算机。G1 GC使用并发(concurrent)和并行(parallel)阶段来实现其目标暂停时间并保持良好的吞吐量。
  • 全堆操作(例如全局标记)与应用程序线程并行执行。这样可以防止与堆或活动数据大小成比例的中断。
  • G1是一个有整理内存过程的垃圾收集器,在回收垃圾的时候会压缩存活对象。不会产生很多内存碎片。
  • G1的Stop The World(STW)更可控,G1在停顿时间上添加了预测机制,用户可以指定期望停顿时间。

并发(concurrent)和并行(parallel)

  • 在单CPU系统中,系统调度在某一时刻只能让一个线程运行,通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent)
  • 在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel)
  • 并发:意味着应用程序同时(并发)在一项以上的任务上取得进展,尽力压榨一个CPU的处理能力,抢占更多的执行时间片
  • 并行:应用程序将其任务分解为较小的子任务,这些子任务可以并行处理,例如在多个CPU上同时进行。重点是多个CPU。

G1GC Region

  • 传统的GC收集器将连续的内存空间划分为新生代、老年代和永久代(JDK 8去除了永久代/PermGen,引入了元空间Metaspace),这种划分的特点是各代的存储地址(逻辑地址)是连续的。
  • G1 GC是一个区域化的代垃圾收集器
  • G1也是分代管理内存的,他的各代存储地址是不连续的,每一代都使用了n个不连续的大小相同的Region,每个Region占有一块连续的虚拟内存地址。

G1GC 停顿预测模型

  • 机器学习听说过吧,这个G1GC里面这个停顿预测模型,就类似这个机器学习,自行训练,自己判断每次回收谁,回收多少。
  • G1 uses a pause prediction model to meet a user-defined pause time target and selects the number of regions to collect based on the specified pause time target.
  • G1 GC是一个响应时间优先的GC收集器,它与CMS最大的不同是,用户可以设定整个GC过程的期望停顿时间,参数-XX:MaxGCPauseMillis指定一个G1收集过程目标停顿时间,默认值200ms,不过它不是硬性条件,只是期望值。那么G1怎么满足用户的期望呢?就需要这个停顿预测模型了。G1根据这个模型统计计算出来的历史数据来预测本次收集需要选择的Region数量,从而尽量满足用户设定的目标停顿时间。

G1GC内部三种形式的GC

G1GC Young GC

Eden区耗尽的时候就会触发新生代收集,新生代垃圾收集会对整个新生代(E + S)进行回收

  • 新生代垃圾收集期间,整个应用STW
  • 新生代垃圾收集是由多线程并发执行的
  • 通过控制年轻代的region个数,即年轻代内存大小,来控制young GC的时间开销。
  • 新生代收集结束后依然存活的对象,会被疏散evacuation到n(n>=1)个新的Survivor分区,或者是老年代。

G1GC Mixed GC

  • Stop The World
  • 选定所有年轻代里的Region,外加根据global concurrent marking统计得出收集收益高的若干老年代Region。在用户指定的开销目标范围内尽可能选择收益高的老年代Region
  • Mixed GC不是full GC,它只能回收部分老年代的Region,如果mixed GC实在无法跟上程序分配内存的速度,导致老年代填满无法继续进行Mixed GC,就会使用serial old GC(full GC)来收集整个GC heap
    什么时候Mixed GC

G1GC FULL GC

  • Stop The World
  • 如果mixed GC实在无法跟上程序分配内存的速度,导致老年代填满无法继续进行Mixed GC,就会使用serial old GC(full GC)来收集整个GC heap。
  • G1是不提供full GC的。这个serial old GC full gc是单线程的(在Java 8中)并且非常慢,因此应避免在G1 gc的时候出现这个full gc 。
  • 不能觉得用了G1gc收集器之后,Java heap里面的gc不是young gc 就mixed gc,还有这个full gc呢

G1GC 支持的配置参数以及默认值

G1GC 支持的配置参数以及默认值
G1GC 支持的配置参数以及默认值

G1 调优建议

  • 不要显式的设置新生代的大小(用Xmn或-XX:NewRatio参数)
  • -XX:ConcGCThreads=n 设置并行标记的线程数。将n设置为并行垃圾回收线程数 (ParallelGCThreads) 的 1/4 左右。
  • -XX:ParallelGCThreads=n 设置 STW 工作线程数的值。将 n 的值设置为逻辑处理器的数量。如果逻辑处理器不止八个,则将n的值设置为逻辑处理器数的 5/8 左右。

G1的推荐使用场景

  • G1的首要重点是为运行需要大堆且GC延迟有限的应用程序的用户提供解决方案。这意味着堆大小约为6GB或更大,并且稳定且可预测的暂停时间低于0.5秒。
  • 如果当前具有CMS或ParallelOld垃圾收集器运行的应用程序具有以下一个或多个特征,则将其切换到G1将非常有益。
  • 超过50%的Java堆被实时数据占用。
  • 对象分配率或提升率差异很大。
  • 不必要的长时间垃圾收集或压缩暂停(长于0.5到1秒)

es7的jvm参数配置

-Xms4g -Xmx4g -XX:+UseG1GC -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30
-XX:InitiatingHeapOccupancyPercent=45
设置触发全局并发标记周期的 Java 堆占用率阈值。默认占用率是整个 Java 堆的 45%。es7调小这个默认值,希望提前触发全局标记降低full gc的风险
-XX:G1ReservePercent=10
设置作为空闲空间的预留内存百分比,以降低目标空间溢出的风险。默认值是 10%。增加或减少百分比时,请确保对总的 Java 堆调整相同的量,es7调大这个值,扩大预留空间。

G1GC实际调优例子

测试程序的jvm参数设置是 -Xmn4G -Xms4G -Xmn64M -XX:+UseG1GC
设置Xmn的Heap情况
分析:

  • 这使用了G1GC的收集器,但是使用了-Xmn 设置了 NewSize的大小
  • 看这个进程的gc情况,每秒都进行10次上下的YGC,很频繁。
  • 看OU是在默默的一点点的增长着呢,预计一下:长着长着,就会塞不下,然后触发full gc了
    删除掉 -Xmn设置之后的heap情况
    删除掉 -Xmn设置之后的heap情况
    分析:
  • 删掉 -Xmn的设置之后的堆内存分布
  • newSize最大可以到 2456MB
  • 4096(Heap) = 2576(E) + 4(S) + 1516(O)
  • 自动分配之后,Y区占比变大,占比 62%
    删除掉 -Xmn设置之后的GC情况
  • 看YGC列,执行次数明显变少几秒钟一次YGCGCT也增长的很慢
  • 再观察OU,有增有减。说明有Mixed GC在执行
  • SEO各区的大小是浮动的
  • 为啥 S0C 和 S0U一直是0?
    结论:
    用这个例子,实际验证了 G1GC的调优建议中的"不要设置New size的大小",因为这个会限制G1GC内部的停顿预测模型的工作,他牛就牛在这个模型上。

对比一下CMS GC

删除掉 -Xmn设置之后的GC情况
S0 和S1是交替在使用,在YGC的时候,有个互相copy的过程

什么时候GC

  • 内存不够用了

对象何时进入老年代

  • 迭代年龄判断 (都知道)
    这个针对的是一个对象长时间存在引用关系,最终在young区来回copy,当年纪大了,就进去old区了。
  • 大对象直接进入老年代(不常见)
    超过单个region区域一半大小的对象,为避免在young区来回的copy,在new的时候直接给安排到old区。
  • YoungGC之后需要移区的对象放不下(基本想不到)
    一般推荐使用G1GC,那都是堆比较大的程序,多半都是处理大量数据的程序,既然是大量数据,那么young区满的速度是贼快的,刷刷刷的就满了。
    若程序运行支持,前脚创建完对象,后脚里面就使用了,那么YoungGC可以很快的回收young区的内存,Old区也不会出现大量的对象。
    这个时候Young区和Old区比例,应该是Young占比比较大才对。
    问题就是对象创建完之后,不是很快的结束引用,这个对象就要在Young区来回的copy,当s区不够的时候,他就会被安排到Old区,对象一旦被copy到old区之后,
    那就只能被Mixed GC或者Full GC来回收了,但是Mixed GC又不是完全的回收Old区的所有没有被引用的对象,他只是挑选一部分回收价值大的对象去回收。
    问题的关键就在这,Mixed GC 1,不是频繁的执行的,2,他还不是回收所有能回收的。当堆内存大量存在可被回收的对象的时候,就会出现浪费的现象。
    一直憋着,直到触发Full GC,STW,来一次大清理。
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-25 12:24:25  更:2021-10-25 12:25:16 
 
开发: 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/23 23:43:11-

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