GC调优
Gc调优的目标:1.降低停顿时间 2.提高吞吐量 3.避免full-gc
调优可以使用的手段:
1.各个内存区的大小调整:堆,年轻代,老年代,方法区等等
2.减少短暂对象的存活时间,提高长期对象的复用率(对象池,cache,永久区等等),减少不必要的垃圾的生产。
3.调整对象的晋升:晋升阈值,survivor的目标存活值,大小等
3.并发控制:并发,并行的gc线程数
3.提前开始并发周期
4.G1可以调整mix-清理周期的目标值,尽快结束mix-清理周期。
1. 降低停顿时间+保存合理的吞吐量:
年轻代:调小年轻代的大小+减少垃圾的产生速度+减少垃圾的存活时间。即,没必要产生的对象就不用创建了,一次性的对象要让它死的快,不容易死的对象要增加复用率。这还有利于减少对象的晋升,减少老年代的压力。
老年代:a.同样可以调小老年代的大小。但是也会带来吞吐量的问题。如果物理内存够大的话,可以使用G1。同样可以减少对象的存活时间,这样可以在老年代的gc中,尽快的清理掉多数的垃圾,可以防止晋升失败和并发失败。
b.加快老年代的gc速度。可以调整并发值,也就是gc的线程数。但是要考虑机器的cpu资源和应用的cpu使用情况,要尽量的提高cpu的使用率,但是不要造成抢占CPU,因为这样会使吞吐量下降。
2. 提高吞吐量:
1. 在gc停顿和频率直接的权衡
2. 线程和cpu资源的考量
3. Gc算法 并行 vs 并发
3. 避免full-gc:
Full-gc的导致有几个原因:1.超大对象 2.并发失败 3.内存碎片 4.永久代满了
并发失败的造成原因是对象的晋升速度超过了老年代的清理速度。所以解决方案就是让这场追赶比赛的悬殊更大一些。
1. 增加堆的大小
2. 降低年轻代的垃圾晋升速度: 对象的快速死亡,减少不必要的对象创建,survivor区调整(目标:充分利用survivor区,保证对象是到达一定年龄才发生晋升而不是 因为溢出而晋升),调大堆区
3. 加快并发周期的速度:并发控制
4. 提前并发周期:提前并发周期(这会导致并发周期的频率增加,所以需要进行权衡),G1调整清理周期目标(清理周期太长,会导致并发周期时间太长,如果清理效率一般,会导致并发失败。清理周期太短,可能会导致并发周期太频繁,清理不够彻底,也有可能导致并发失败,所以也需要进行权衡)
5. 提高老年代收集效率:减少对象生命周期
survivor区的调优:
目标: 1. 最基本的目标是保证对象是因为达到晋升阈值才到达老年代,而不是因为溢出而到达老年代 2. 在目标1的基础上,尽可能的加大对象的晋升阈值,这样可以减轻老年代的压力,当然也要考虑这样给年轻代造成的压力。最好不要为了这个目标而把老年代调小,这样会使full-gc的风险加大
方法:1. 晋升阈值的设置:-XX:MaxTenuringThreshold(最大晋升阈值) -XX:InitialTenuringThreshold=N (初始晋升阈值) ,有时为了避免溢出导致的晋升,不得已把晋升阈值调小
2. 设置survivor区的目标利用率(YGC后,survivor的占用率) -XX:TargetSurvivorRatio 默认是50,一般这也是合适的
3. 减少对象的存活时间
4.调整堆的大小
思路:
1. -XX:+PrintTenuringDistribution 使用这个参数,gc日志会打印各个年龄的对象的大小,再通过survivor的大小,我们就可以推断是否会发生溢出了,也可以根据survivor的大小设置合适的晋升阈值和目标值
2. 不可把survivor增加过大,因为会对象是直接在eden上分配的,如果eden减少,会带来更多的性能问题。也不可过多减少老年代的大小,这样会导致full-gc风险加大。最好的方法是增加堆的大小,调小survivor的利于率目标值。这样eden和老年代都大概维持原有的大小,survivor区会加大。
TLAB: TLAB位于Eden区,是线程的进行快速分配内存是区域。因为它是thread local的,不像TLAB外的区域需要进行同步操作,所以比较快。当一个线程的tlab用尽的时候,有俩种动作:1. 直接在tlab外进行分配对象,这个线程后续的分配还会尝试往这个tlab上进行分配。 2. 放弃这个tlab,在eden区重新分配一块新的tlab。老的tlab会随着ygc进行垃圾回收,但是老的tlab上的剩余空间会被浪费。 操作这俩个动作的选择是-XX:TLABWasteTargetPercent=N -XX:TLABWasteIncrement=N -XX:TLABSize=N
这些参数。它的大小默认是动态计算的。每次在tlab外分配完成后,都会使TLABWasteTargetPercent的值变大。
Tlab的大小默认由三个因素控制:应用程序的线程数、Eden 空间的大小以及线程的分配率 使用 -XX:-UseTLAB 可以关闭tlab
大对象: 当一个大对象无法在年轻代放得下时,就回直接进入老年代。 在G1中,如果大对象大于一个分区的大小,就会被放到老年代,而且在老年代中需要连续的分区来进行存放。如果没有连续的分区,就会触发并发周期,如果还不行,就会进行full-gc。所以大对象的影响是很大的。
G1调优:
G1 垃圾收集器调优的主要目标是避免发生并发模式失败或者疏散失败
• 通过增加总的堆空间大小或者调整老年代、新生代之间的比例来增加老年代空间的 大小。
• 增加后台线程的数目(假设我们有足够的CPU资源运行这些线程)。
• 以更高的频率进行G1的后台垃圾收集活动。
• 在混合式垃圾回收周期中完成更多的垃圾收集工作。
调优方法:
1. 使用 -XX:MaxGCPauseMillis=N 但是如果过小的话,会导致年轻代和老年代都变小,从而导致gc频繁,full-gc风险变大。
2. 增加后台并发数 ParallelGCThreads ConcGCThreads
3. 调整并发周期频率,尽早开始清理:-XX:InitiatingHeapOccupancyPercent=N G1是根据整个堆区,CMS是根据老年代的大小占用 太大会导致full-gc风险变高,太小会导致gc太频繁
4. 调整混合清理周期:并发周期之后、老年代的标记分区回收完成之前,G1 收集器无法启动新的并发周期。因此,让 G1 收集器更早启动标记周期的另一个方法是在混合式垃圾回收周期中尽量处理更 多的分区(如此一来最终的混合式 GC 周期就变少了,但是单次清理周期的停顿时间呼会变长):
混合式垃圾收集要处理的工作量取决于三个因素。
第一个因素是有多少分区被发现大部分 是垃圾对象。目前没有标志能够直接调节这个因素:混合式垃圾收集中,如果分区的垃圾 占用比达到 35%,这个分区就被标记为可以进行垃圾回收。(这个因素在将来的某个时刻 可能也能调整,在开源的实验版本中已经有名为 -XX:G1MixedGCLiveThresholdPercent=N 的 参数可以对其进行调整)。
第二个因素是 G1 垃圾收集回收分区时的最大混合式 GC 周期数,通过参数 -XX:G1MixedGCCountTarget=N 可以进行调节。这个参数的默认值为 8;减少该参数值可以帮 助解决晋升失败的问题(代价是混合式 GC 周期的停顿时间会更长)。
另一方面,如果混合式 GC 的停顿时间过长,可以增大这个参数的值,减少每次混合式 GC 周期的工作量。不过调整之前我们需要确保增大值之后不会对下一次 G1 并发周期带来 太大的延迟,否则可能会导致并发模式失败。
最后,第三个影响因素是 GC 停顿可忍受的最大时长(通过 MaxGCPauseMillis 参数设定)。 MaxGCPauseMillis 标志设定的混合式周期时长是向上规整的,如果实际停顿时间在停顿最大时长以内,G1 收集器能够收集超过八分之一标记的老年代分区(或者其他设定的值)。 增大 MaxGCPauseMillis 能在每次混合式 GC 中收集更多的老年代分区,而这反过来又能帮 助 G1 收集器在更早的时候启动并发周期。
CMS调优:
CMS和G1的不同是,它的清理算法是标记清理,所以最后的清理是并发的,不会造成stw,所以不需要考虑g1中混合清理阶段的一些问题。
CMS的调优目标也是避免并发失败:
做法:
1.想办法增大老年代空间,要么只移动部分的新生代对象到老年代,要么增加更多的堆 空间。
2.以更高的频率运行后台回收线程。 -XX:CMSInitiatingOccupancyFraction=N 和 -XX:+UseCMSInitiatingOccupancyOnly CMSInitiatingOccupancyFraction值的确定,可以先找到一个并发失败的日志,然后查看这次并发周期开始时,老年代的占用比。
3.使用更多的后台回收线程。
GC调优的更多相关文章
- Java GC 专家系列3:GC调优实践
本篇是”GC专家系列“的第三篇.在第一篇理解Java垃圾回收中我们学习了几种不同的GC算法的处理过程,GC的工作方式,新生代与老年代的区别.所以,你应该已经了解了JDK 7中的5种GC类型,以及每种G ...
- GC参考手册 —— GC 调优(基础篇)
GC调优(Tuning Garbage Collection)和其他性能调优是同样的原理.初学者可能会被 200 多个 GC参数弄得一头雾水, 然后随便调整几个来试试结果,又或者修改几行代码来测试.其 ...
- GC参考手册 —— GC 调优(工具篇)
JVM 在程序执行的过程中, 提供了GC行为的原生数据.那么, 我们就可以利用这些原生数据来生成各种报告.原生数据(raw data) 包括: 各个内存池的当前使用情况, 各个内存池的总容量, 每次G ...
- 性能测试系列-java gc调优
性能测试中除了需要做好性能测试外,我们还需要做性能测试后的,性能调优,需要发现性能问题,也需要做性能调优,在做性能调优中,jvm的性能调优是经常遇到的一个. 随着jdk版本的迅速变化,jdk里面的GC ...
- GC调优在Spark应用中的实践(转载)
Spark是时下非常热门的大数据计算框架,以其卓越的性能优势.独特的架构.易用的用户接口和丰富的分析计算库,正在工业界获得越来越广泛的应用.与Hadoop.HBase生态圈的众多项目一样,Spark的 ...
- GC调优入门笔记
想给项目代码做做调优但有许多疑惑,比如有哪些参数要调.怎么调.使用什么工具.调优的效果如何定量测量等.发现Oracle的这份资料不错,简洁直接,回答了我的许多问题,给了许多很实用的大方向上的指导.将其 ...
- GC调优在Spark应用中的实践[转]
作者:仲浩 出处:<程序员>电子刊5月B 摘要:Spark立足内存计算,常常需要在内存中存放大量数据,因此也更依赖JVM的垃圾回收机制.与此同时,它也兼容批处理和流式处理,对于程序 ...
- gc调优我们到底在调整什么
java开发一般都会涉及到jvm调优其中gc调优是个重点项.那gc调优调整的究竟是什么呢准确来说是业务.下面围绕这个话题展开 起因 为什么说是业务呢得从cc++开始说起如果说是用c/c++做开发运行的 ...
- 深入JVM系列(二)之GC机制、收集器与GC调优
一.回想JVM内存分配 须要了解很多其它内存模式与内存分配的,请看 深入JVM系列(一)之内存模型与内存分配 1.1.内存分配: 1.对象优先在EDEN分配 2.大对象直接进入老年代 3.长期存活的 ...
随机推荐
- 随便说说sequelize的问题
最近在做的项目频繁的修改数据库让人感觉很烦躁,sequelize在执行sync的时候只会重新创建表,如果原先有数据只能直接删除,但是这样显然是不行的,因为数据不能就这么消失了吧. 所以必须要migra ...
- 第三篇 Flask 中的 request
第三篇 Flask 中的 request 每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前 ...
- 10.17 elemen.js
今天终于把element.js的官方文档看完了,主要是基础组件的用法,看的时候有种之前学bootstrap的感觉,似曾相识. 虽然它是基于VUE的,但是展示给我们的代码已经精简到不用会VUE也能看懂了 ...
- mysql7.5.x删除重新安装
删除: cmd管理员运行,进入D:\devs\MySQL\mysql-5.7.25-winx64\bin目录下: 输入命令:sc delete mysql 删除data目录下的所有文件 安装: 创建m ...
- JavaSE基础知识(5)—面向对象(5.4面向对象三大特征:封装、继承、多态)
面向对象编程具有三大特征: 封装 继承 多态 一.封装 1.好处 狭义的封装:也就是属性的封装,避免了任意赋值的危险,提高了数据的安全性! ①隐藏一个类中不需要对外提供的实现细节 ②使用者只能通过实现 ...
- angular ViewChild ContentChild 系列的查询参数
官方说明 官方文档 在调用 NgAfterViewInit 回调函数之前就会设置这些视图查询. 元数据属性: selector - 用于查询的指令类型或名字. read - 从查询到的元素中读取另一个 ...
- “无法将“Enable-Migrations”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。”的一种解决方式
通过以下几个步骤解决: 1.install-package entityFramework: 2.更新 nuget: 3.更新 visual studio: 我是通过第三个步骤解决的.
- docker安装nginx和php
参考文章:https://www.cnblogs.com/boundless-sky/p/7182410.html 1.下载镜像docker pull nginxdocker pull php:7.2 ...
- 配置GitHub的SSH key
配置GitHub的SSH key 生成密钥对 打开git bash工具(Windows环境),Linux则直接打开命令行,执行下面的命令生成密钥文件 ssh-Keygen -t rsa -C &quo ...
- SSL及使用openssl实现CA
TLS如何实现各种功能?数据如何加密在网络上传输? 网景(Netscape)公司在应用层和传输层加入了半层,把这个半层称之为SSL,SSL不是软件,可以理解是一个库,当http交给tcp层之前先通过s ...