• 极客文库-知识库上线!
  • 极客文库小编@勤劳的小蚂蚁,为您推荐每日资讯,欢迎关注!
  • 每日更新优质编程文章!
  • 更多功能模块开发中。。。

一次生产的JVM优化

生产环境有二台阿里云服务器,均为同一时期购买的,CPU、内存、硬盘等配置相同。具体配置如下:
由于这二服务器硬件和软件配置相同,并且运行相同的程序,所以在 Nginx 轮询策略均 weight=1,即平台的某个流量由这二台机器平分。
有一次对系统进行例行检查,使用 PinPoint 查看下服务器”Heap Usage”的使用情况时,发现,在有一个系统 Full GC 非常频繁,大约五分钟一次 Full GC(如果不明白 Full GC 的什么意思的,请自行百度),吓我一跳。这么频繁的 Full GC,导致系统暂停处理业务,对系统的实时可用性大打折扣。我检查了一下 Tomcat(Tomcat8.5.28)配置,发现在 tomcat 没有作任何关于 JVM 内存的设置,全部使用默认模式。由于这二服务器硬件和软件配置相同,并且运行相同的程序,所以在 Nginx 轮询策略均 weight=1,即平台的某个流量由这二台机器平分。 

GC 数据:

在业务峰期间,通过 PinPoint 观察的 A、B 节点的”Heap Usage”使用情况,分别进行以下几个时间段数据。

3 小时图:


上图 B 系统在三个小时内,一共发生了 22 次 Full GC,大约每 8 分钟进行一次 Full GC。每次 Full GC 的时间大概有 150ms 左右,即 B 系统在三个小时内,大约有 3300ms 暂停系统运行。从上图来看,堆的空间最大值在 890M 左右,但在堆空间的大小大约 200M 就发生 Full GC 了,从系统资源的利用角度来考虑,这个使用率太低了。

上图 A 系统在 3 个小时内,一共发生了 0 次 Full GC,嗯,就是没有任何停顿。 在这 3 小时,系统一直在处理业务,没有停顿。堆的总空间大约 1536m,目前堆的空间大于 500M。

6 小时图:


上图 B 系统在 6 个小时的数据统计和 3 个小时很像,6 个小时内一共发生了 N 次 Full GC,均是堆的空间小于 200M 就发生 Full GC 了。

上图 A 系统在 6 个小时内,一共发生了 0 次 Full GC,表现优秀。

12 小时图:


上图 B 系统在 12 个小时内,一共发生了 N 次 Full GC,左边 Full GC 比较少,是因为我们的业务主要集中白天,虽然晚上属于非业务高峰期间,还是有 Full GC。
上图 A 系统在 12 个小时内,一共发生了 0 次 Full GC,表现优秀。 

GC 日志:

看下 gc.log 文件,因为我们两台服务器都输出了 gc 的详细日志,先看下 B 系统的 Full GC 日志。
上图全部是”
  1. [
    Full
    GC (
    Ergonomics
    )”日志,是因为已经去掉” GC (
    Allocation
    Failure
    ”日志,这样更方便观察和分析日志,选取 GC 日志文件最后一条
    Full
    GC 日志。

  2.    
    2018
    -
    12
    -
    24T15
    :
    52
    :
    11.402
    +
    0800
    :
    447817.937
    : [
    Full
    GC (
    Ergonomics
    ) [
    PSYoungGen
    :
    480K
    ->
    0K
    (
    20992K
    )] [
    ParOldGen
    :
    89513K
    ->
    69918K
    (
    89600K
    )]

  3.    
    89993K
    ->
    69918K
    (
    110592K
    ), [
    Metaspace
    :
    50147K
    ->
    50147K
    (
    1095680K
    )],
    0.1519366
    secs] [
    Times
    : user=
    0.21
    sys=
    0.00
    , real=
    0.15
    secs]

可以计算得到以下信息: 堆的大小:110592K=108M 老生代大小:89600K=87.5M 新生代大小:20992K=20.5M
分析:这次 Full GC 是因为老年代对象占用的空间的大小已经超过老年代容量 ([ParOldGen: 89513K->69918K(89600K)])引发的 Full GC。是因为分配给老年代的空间太小,远远不能满足系统对业务的需要,导致老年代的空间常常被占满,老年代的空间满了,导致的 Full GC。由于老年代的空间比较小,所以每次 Full GC 的时间也比较短。 A 系统日志,只有 2 次 Full GC,这 2 次 GC 均发生在系统启动时:
  1. 7.765
    : [
    Full
    GC (
    Metadata
    GC
    Threshold
    ) [
    PSYoungGen
    :
    18010K
    ->
    0K
    (
    458752K
    )] [
    ParOldGen
    :
    15142K
    ->
    25311K
    (
    1048576K
    )]
    33153K
    ->
    25311K
    (
    1507328K
    ), [
    Metaspace
    :
    34084K
    ->
    34084K
    (
    1081344K
    )],
    0.0843090
    secs] [
    Times
    : user=
    0.14
    sys=
    0.00
    , real=
    0.08
    secs]

可以得到以下信息:
堆的大小:1507328K=1472M 老生代大小:89600K=1024M 新生代大小:20992K=448M
分析:A 系统只有系统启动才出现二次 Full GC 现象,而且是” Metadata GC Threshold”引起的,而不是堆空间引起的 Full GC。虽然经过一个星期的观察,A 系统没有 Full GC,但一旦发生 Full GC 时间则会比较长。其它系统增加发现过,1024M 的老年代,Full GC 持续的时间大约是 90ms 秒。所以看得出来推也不是越大越好,或者说在 UseParallelOldGC 收集器中,堆的空间不是越大越好。 分析与优化

总体分析:

B 系统的 Full GC 过于频繁,是因为老生代只有约 108M 空间,根本无法满足系统在高峰时期的内存空间需求。由于 ParOldGen(老年代)常常被耗尽,所以就发生 Full GC 事件了。 A 系统的堆初始空间(Xms)和堆的最大值(Xmx)均为 1536m,完全可以满足业务高峰期的内存需求。

优化策略:

B 系统先增加堆空间大小,即通过设置 Xms、 Xmx 值增加堆空间。直接把 Xms 和 Xmx 均设置为 1024M。直接堆的启动空间(Xms)直接设置为堆的最大值的原因是:因为直接把 Xms 设置为最大值(Xmx)可以避免JVM运行时不停的进行申请内存,而是直接在系统启动时就分配好了,从而提高系统的效率。把 Xms(堆大小)设置为 1024M,是因为采用 JDK 的建议,该建议通过命令得到”

  1. java -XX:+
    PrintCommandLineFlags
    -version” 。![](index_files/
    0.8277313893055347
    .png)其中,“-XX:
    MaxHeapSize
    =
    1004719104
    ”,.

即 Xmx 为 1024M,其它建议暂时不采纳。所以综合下来的 B 系统的JVM参数设置如下:
  1. export
    JAVA_OPTS=
    "-server –Xms1024m -Xmx1024m -XX:+UseParallelOldGC  -verbose:gc -Xloggc:../logs/gc.log  -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"

A 系统JVM参数设置保持不变,以便观察系统运行情况,即:
  1. export
    JAVA_OPTS=
    "-server -Xms1536m -Xmx1536m -XX:+UseParallelOldGC  -verbose:gc -Xloggc:../logs/gc.log  -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"

将 A、B 节点系统的 JVM 参数采用 2 套参数,是为了验证 A 或 B 的参数更适合实际情况。

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:一次生产的 JVM 优化
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

欢迎 注册账号 登录 发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ

247507792

工作时间:09:00-23:00

新浪微博:点我访问

个人博客:点我访问