GC调优对我们开发人员来说,如果你想要技术方面一直发展下去,这部分内容的了解是必不可少的,jvm对于工作、面试来说都很重要,GC调优的问题

更是重中之重,因为是对你jvm学习内容的实践,知识只有应用实践出来才有意义,否则知识纸上谈兵。

首先,我们需要了解的内容,包括:

1、jvm内存结构:java虚拟(一)--java内存区域和常量池概念

2、垃圾收集算法:java虚拟机(五)--垃圾回收机制GC

3、常见的垃圾收集器:java虚拟机(六)--垃圾收集器和内存分配策略

4、GC日志分析:java虚拟机(十一)--GC日志分析    java虚拟机(十二)--可视化工具分析GC日志

5、jvm常见参数:java虚拟机(九)--常用jvm参数

PS:本文GC调优非生产环境,只是个人Linux系统对一个简单项目的启动调优,通过GC日志调整相关参数,学习GC调优的方法,最终在生产环境得到应用

网上有很多生产环境GC调优的案例,请自行参考

垃圾回收器的主要衡量标准:

1、吞吐量

2、最大停顿时间

GC调优步骤:

1、打印GC日志

2、根据日志获得关键性能指标

3、分析GC原因,调优JVM参数

Parallel GC调优:

官网建议:

1、除非确定,否则不要设置最大堆内存

2、优先设置吞吐量目标

3、如果吞吐量目标达不到,调大最大内存,不能让OS使用Swap,如果任然达不到,降低目标

4、如果吞吐量能达到,GC时间太长,设置停顿时间的目标

首先设置参数:

JAVA_OPTS="-XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$CATALINA_HOME/logs/ -XX:+PrintGCDetails
-XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log"

-XX:+DisableExplicitGC:是指禁止代码中通过system.gc()主动调用GC

将生成的GC日志通过GCeasy分析,首先看到吞吐量为93.78%

发生12GC,2次Full GC,10次Minor GC,Minor GC和Full GC的时间如下:

GC发生的原因:

其中Ergonomics导致一次Full GC,耗时为130ms,时间最长

Metadata GC Threshold导致发生1次Full GC,一次Minor GC

Allocation Failure和GCLocker Initiated GC导致9次Minor GC

调优步骤如下:调优就是实验的过程

其中Ergonomics为jvm的自适应,根据CPU和内存情况自行调节jvm内存结构,但是也导致了一次Full GC

官方建议:除非很确定,否则不要设置最大堆内存,所以这里不调节堆内存

1、因为Metaspace GC Thread出现Full GC,所以这里选择调节-XX:MetaspaceSize=64M,因为最大使用了22.74M

吞吐量有了提高,GC次数降低,最大GC Pause为70ms,所以我们对于MetaspaceSize的调节是对的

2、对于一个测试项目来说,我们只是测试启动GC,95.94%的吞吐量,不够高,所以这里测试一下:

-XX:MaxGCPauseMillis=100 -XX:GCTimeRatio=99,最大GC时间位100ms,吞吐量为99%

发现为了提高吞吐量,吞吐量有了小幅度提升,但是GC时间却增长了很多

11次GC中有10次Minor GC,原因都是Allocation Failure

3、我们选择内存动态扩容增量参数,调节为30,我们查询直到,默认为20%

# jinfo -flag YoungGenerationSizeIncrement 25436
-XX:YoungGenerationSizeIncrement=20

调节发现,吞吐量为94.346%,所以这里这个参数不太适合

所以GC调优就是不断试验的过程,调优的次数多了,就有了经验,还有其他很多参数,都可以试验测试,查看起到的作用

PS:我这里测试的参数可能和你的项目以及环境不同,起到的作用可能不同,例如动态扩容参数,换个项目可能就会有好的作用

G1调优:jdk1.8一般采用G1

官网建议:

1、年轻代大小:

  避免使用-Xmn、-XX:NewRatio等显式设置Young区大小,会覆盖暂定时间目标

2、暂停时间目标:

  暂停时间不要太苛刻,吞吐量目标为90%,太严苛影响吞吐量

3、关于Mixed GC调优参数:

-XX:InitiatingHeapOccupancyPercent:

  堆占有率达到这个数值则触发global concurrent marking,默认45%

-XX:G1HeapWastePercent:

  在global concurrent marking结束之后,可以知道区中有多少空间要被回收,在每次YGC之后和再次发生Mixed GC之前,会检查垃圾占比是

否达到这个参数,如果达到了,下次才会发生Mixed GC。

-XX:G1MixedGCLiveThresholdPercent:

  Old区Region被回收的时候,存货对象的占比

-XX:G1MixedGCCountTarget:

-XX:G1OldSetRegionThresholdPercent:

调优步骤如下:

1、默认情况下

When you see to-space overflow or to-space exhausted messages in your logs, the G1 GC does not have enough memory for either survivor or promoted objects, or for both. The Java heap cannot because it is already at its maximum. Example messages:

924.897: [GC pause (G1 Evacuation Pause) (mixed) (to-space exhausted), 0.1957310 secs]

924.897: [GC pause (G1 Evacuation Pause) (mixed) (to-space overflow), 0.1957310 secs]

To alleviate the problem, try the following adjustments:

Increase the value of the -XX:G1ReservePercent option (and the total heap accordingly) to increase the amount of reserve memory for "to-space".

Start the marking cycle earlier by reducing the value of -XX:InitiatingHeapOccupancyPercent.

Increase the value of the -XX:ConcGCThreads option to increase the number of parallel marking threads.

上面是官方建议:

  对于Mixed GC,可以增加-XX:G1ReservePercent选项的值(以及相应的总堆)以增加“to-space”的保留内存量

总共测试四次,如下表格:

  最后修改的参数:-XX:GCTimeRatio=100,理论上对于G1垃圾收集器应该是很重要的,因为本身就是强调吞吐量,只是本次测试只是小的测试项目,

而且服务器配置比较渣,只有2个CPU,有些参数无法试验

总结:

  我们可以通过官方文档的建议,通过GC日志,结合解析工具,无论是GCeasy还是GC View都是可以的,通过发生GC的原因等问题逐渐调节参数,

官方文档一定要多看几遍,我只是简单浏览而已,后面肯定会仔细看的。

GC调优指南:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/toc.html

如何选择垃圾收集器:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html

G1最佳实践:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations

G1 GC的一些关键技术:https://zhuanlan.zhihu.com/p/22591838

java虚拟机(十三)--GC调优思路的更多相关文章

  1. java虚拟机性能监控调优及原则

    摘抄 http://uule.iteye.com/blog/2114697 一.JVM内存模型及垃圾收集算法  1.根据Java虚拟机规范,JVM将内存划分为: New(年轻代) Tenured(年老 ...

  2. Java虚拟机学习 - 内存调优 ( 9 )

    JVM调优主要是针对内存管理方面的调优,包括控制各个代的大小,GC策略.由于GC开始垃圾回收时会挂起应用线程,严重影响了性能,调优的目是为了尽量降低GC所导致的应用线程暂停时间. 减少Full GC次 ...

  3. 【java虚拟机】jvm调优原则

    转自:https://www.cnblogs.com/xiaopaipai/p/10522794.html 合理规划jvm性能调优 JVM性能调优涉及到方方面面的取舍,往往是牵一发而动全身,需要全盘考 ...

  4. java虚拟机学习-JVM调优总结-调优方法(12)

    JVM调优工具 Jconsole,jProfile,VisualVM Jconsole : jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用.对垃圾回收算法有很详细的跟踪.详细说明参考这里 ...

  5. java虚拟机学习-JVM调优总结-分代垃圾回收详述(9)

    为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象, ...

  6. 29、Java虚拟机垃圾回收调优

    一.背景 如果在持久化RDD的时候,持久化了大量的数据,那么Java虚拟机的垃圾回收就可能成为一个性能瓶颈.因为Java虚拟机会定期进行垃圾回收,此时就会追踪所有的java对象, 并且在垃圾回收时,找 ...

  7. java虚拟机学习-JVM调优总结-新一代的垃圾回收算法(11)

    垃圾回收的瓶颈 传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最小,把应用的吞吐量推到了一个极限.但是他无法解决的一个问题,就是Full GC所带来的应用暂停.在一些对实时性要 ...

  8. java虚拟机学习-JVM调优总结-典型配置举例(10)

    以下配置主要针对分代垃圾回收算法而言. 堆大小设置 年轻代的设置很关键 JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理 ...

  9. 【java虚拟机】jvm调优

    转自:https://www.cnblogs.com/starhu/p/6400348.html?utm_source=itdadao&utm_medium=referral 堆大小设置JVM ...

随机推荐

  1. thinkphp 模型定义

    模型定义 模型类并非必须定义,只有当存在独立的业务逻辑或者属性的时候才需要定义. 模型类通常需要继承系统的\Think\Model类或其子类,下面是一个Home\Model\UserModel类的定义 ...

  2. Unknown/unsupported SVM type in function 'cv::ml::SVMImpl::checkParams'

    1.在使用PYTHON[Python 3.6.8]训练样本时报错如下: Traceback (most recent call last): File "I:\Eclipse\Python\ ...

  3. duilib教程之duilib入门简明教程14.部分bug 2

    上一个教程中提到了ActiveX的Bug,即如果主窗口直接用变量生成,则关闭窗口时会产生崩溃      如果用new的方式生成,则不会崩溃,所以给出一个临时的快速解决方案,即主窗口都用new生成,_t ...

  4. Visual Studio 2010 error C2065: '_In_opt_z_' : undeclared identifier 编译错误

    当用Visual Studio 2010 编译时 发生如下编译错误: 2>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\inclu ...

  5. 小程序跳坑 --- navigator 和 API中wx.系列的跳转(如 wx.navigateTo、wx.reLaunch等)

    工作之余,想着帮老妈开发个小程序,一是宣传一下她的业务,二是学习使用一下微信小程序的开发,哈哈.在此过程中遇到了navigator跳转的问题,最终还是成功解决了,下面就记录下来,并做个系列总结以作记录 ...

  6. 深入分析Service启动、绑定过程

    Service是Android中一个重要的组件,它没有用户界面,可以运行在后太做一些耗时操作.Service可以被其他组件启动,甚至当用户切换到其他应用时,它仍然可以在后台保存运行.Service 是 ...

  7. import socket模块

    编写两个小脚本实现聊天功能0.1: 脚本一,服务器端:server.py import socket # 调用模块 sk = socket.socket() # 创建socket addess = ( ...

  8. 18-2-call和apply

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. mac下Spark的安装与使用

    每次接触一个新的知识之前我都抱有恐惧之心,因为总认为自己没有接触到的知识都很高大上,比如上篇介绍到的Hadoop的安装与使用与本篇要介绍的Spark,其实在自己真正琢磨以后才发现本以为高大上的知识其实 ...

  10. MapReduce模型简介