线上Java程序的JVM频繁FGC,现象如图所示:

一直持续FGC 5次左右,每次耗时1秒多不等。

FGC的原因实际上是内存不够用,但是运维反映堆内存是2G,从运维提供的参数看也是。

内存实际上一直只用到1G以内。

这时候可以自己写一段代码输出堆内存数据,这是最准的:

public class JVMTest {public static void main(String[] args) throws Exception {MemoryMXBean mxb = ManagementFactory.getMemoryMXBean();//HeapSystem.out.println("Max:" + mxb.getHeapMemoryUsage().getMax() / 1024 / 1024 + "MB");    //Max:1776MBSystem.out.println("Init:" + mxb.getHeapMemoryUsage().getInit() / 1024 / 1024 + "MB");  //Init:126MBSystem.out.println("Committed:" + mxb.getHeapMemoryUsage().getCommitted() / 1024 / 1024 + "MB");   //Committed:121MBSystem.out.println("Used:" + mxb.getHeapMemoryUsage().getUsed() / 1024 / 1024 + "MB");  //Used:7MBSystem.out.println(mxb.getHeapMemoryUsage().toString());    //init = 132120576(129024K) used = 8076528(7887K) committed = 126877696(123904K) max = 1862270976(1818624K)//Non heapSystem.out.println("Max:" + mxb.getNonHeapMemoryUsage().getMax() / 1024 / 1024 + "MB");    //Max:0MBSystem.out.println("Init:" + mxb.getNonHeapMemoryUsage().getInit() / 1024 / 1024 + "MB");  //Init:2MBSystem.out.println("Committed:" + mxb.getNonHeapMemoryUsage().getCommitted() / 1024 / 1024 + "MB");   //Committed:8MBSystem.out.println("Used:" + mxb.getNonHeapMemoryUsage().getUsed() / 1024 / 1024 + "MB");  //Used:7MBSystem.out.println(mxb.getNonHeapMemoryUsage().toString());    //init = 2555904(2496K) used = 7802056(7619K) committed = 9109504(8896K) max = -1(-1K)}
}

参考:https://www.cnblogs.com/songxingzhu/p/9106394.html

这是本地的测试数据,很明显自己设定的内存都生效了,然后拿到线上一跑果然实际堆最大内存是900多M,所以内存触发了阈值就FGC。所以FGC的根源还是内存不够,运维设置不对,运维设置了2G,但是实际上由于使用上的问题不生效

所以要用数据说话,不要去猜测,也不要过度相信配置,因为已经FGC了,而且内存上不了1G。

java-Xms64m #JVM启动时的初始堆大小-Xmx128m #最大堆大小-Xmn64m #年轻代的大小,其余的空间是老年代-XX:MaxMetaspaceSize=128m #-XX:CompressedClassSpaceSize=64m #使用 -XX:CompressedClassSpaceSize 设置为压缩类空间保留的最大内存。-Xss256k #线程-XX:InitialCodeCacheSize=4m #-XX:ReservedCodeCacheSize=8m # 这是由 JIT(即时)编译器编译为本地代码的本机代码(如JNI)或 Java 方法的空间-XX:MaxDirectMemorySize=16m-XX:NativeMemoryTracking=summary #开启内存追踪-jar app.jar

#java -Xms2048m -Xmx2048m  -Xmn64m   -cp Test-1.0.0.jar com.test.JVMTest  start

这个只是本地模拟,线上参数需要比这个复杂。

再回到前面的问题为什么回运维设置不生效呢?

因为这个原因:

Java 8u131及以上版本开始支持了Docker的cpu和memory限制。

cpu limit

即如果没有显式指定-XX:ParalllelGCThreads 或者 -XX:CICompilerCount, 那么JVM使用docker的cpu限制。如果docker有指定cpu limit,jvm参数也有指定-XX:ParalllelGCThreads 或者 -XX:CICompilerCount,那么以指定的参数为准。

memory limit

在java8u131+及java9,需要加上-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap才能使得Xmx感知docker的memory limit。

-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap (正确的识别容器限制,910.50M)安全

关于这个解释可以参考此文即可:http://virtual.51cto.com/art/201901/589723.htm

具体使用不使用这个参数需要结合实际情况。

后来据运维说是参数配置问题:

java -server -jar XXX.jar -Xms2048m -Xmx2048m 这是错的

java -server -jar -Xms2048m -Xmx2048m XXX.jar 要这样

延申阅读:记一次频繁FGC的简单排查

一次JVM GC长暂停的排查过程

Java线上程序频繁JVM FGC问题排障与启示相关推荐

  1. 【深入理解JVM】JAVA线上故障排查全套路

    线上故障主要会包括cpu.磁盘.内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍.同时例如jstack.jmap等工具也是不囿于一个方面的问题的,基 ...

  2. linux 内存溢出排查_记一次JAVA 线上故障排查完整套路

    JAVA线上故障排查全套路 线上故障主要会包括cpu.磁盘.内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍.同时例如jstack.jmap等工具也 ...

  3. Java线上问题排查思路及Linux常用问题分析命令学习

    前言 之前线上有过一两次OOM的问题,但是每次定位问题都有点手足无措的感觉,刚好利用星期天,以测试环境为模版来学习一下Linux常用的几个排查问题的命令. 也可以帮助自己在以后的工作中快速的排查线上问 ...

  4. Java 线上问题排查思路与工具使用

    本文来自作者 蓬蒿 在 GitChat 上分享 「Java 线上问题排查思路与工具使用」,「阅读原文」查看交流实录. 「文末高能」 编辑 | 哈比 一.前言 Java 语言是当前互联网应用最为广泛的语 ...

  5. JAVA线上问题排查及常用命令

    前言 线上问题排查是程序员绕不开路.线上故障主要会包括 CPU.磁盘.内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍.同时例如 jstack.jm ...

  6. 老九java线上_java应用监测(4)-线上问题排查套路

    tags: java, troubleshooting, monitor 一句话概括:java应用线上问题如CPU过高,内存溢出,IO过高等问题如何排查,本文为你详细讲述. 1 引言 java应用上线 ...

  7. java线上问题定位_java定位线上问题

    3.jstack: Java 提供的命令.可以查看某个进程的当前线程栈运行情况.根据 这个命令的输出可以定位某个进程的所有线程的当前运行状态.运行代码,以及 是否死锁等等...... A.//int ...

  8. Arthas - Java 线上问题定位处理的终极利器

    前言 在使用 Arthas 之前,当遇到 Java 线上问题时,如 CPU 飙升.负载突高.内存溢出等问题,你需要查命令,查网络,然后 jps.jstack.jmap.jhat.jstat.hprof ...

  9. 线上FullGC频繁的排查

    线上FullGC频繁的排查 问题 前段时间发现线上的一个dubbo服务Full GC比较频繁,大约每两天就会执行一次Full GC. Full GC的原因 我们知道Full GC的触发条件大致情况有以 ...

最新文章

  1. 机器学习笔试题精选(四)
  2. ListView 排序
  3. 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员赋值及源码分析 )
  4. 域滤波:方框、高斯、中值、双边滤波
  5. 基于TextRank的关键词提取算法
  6. Scala与Java差异(四)之数组操作
  7. 1 MM配置-企业结构-定义-定义评估级别
  8. JavaScript变量作用域如何像多个级别的政府一样
  9. linux下RTNETLINK answers: File exists的解决方案
  10. switchhosts使用
  11. 第二届上汽零束SOA平台开发者大会揭幕,智能汽车生态加速落地
  12. 方舟非主机服务器无限距离,方舟生存进化怎么调主机距离
  13. 【高项】沟通管理(ITTO)
  14. 在 Windows 系统下常用的 bat 脚本分享
  15. 高丽参的作用与功效及忌讳
  16. 如何在Ubuntu下为SI安装Fixedsys字体
  17. openfeign调用异常:feign.FeignException: [405] during [GET]
  18. ora-01237 ora-01110 ora-17505 ora-15041
  19. UCloud邱模炯:为什么内核是云平台稳定性的关键
  20. YOLO系列目标检测算法-YOLOv6

热门文章

  1. rust腐蚀 木制窗户怎么修_装修窗帘怎么选最划算?记住这3点,至少能省大几千...
  2. java intent 传递集合对象_Intent之对象传递(Parcelable传递对象和对象集合)
  3. fork() || fork() || fork() 与 fork() fork() fork()
  4. Linxu终端gcc与gcc -c的区别
  5. delphi socket 流的使用_基于TCP协议的Socket编程和通信_单向通信
  6. Python Qt GUI设计:QMdiArea和QMdiSubWindow类实现多文档界面(拓展篇—3)
  7. Python图像拼接:创建全景图
  8. android组件什么时候加载到r文件,Android自定义加载loading view动画组件
  9. USTC并行计算复习
  10. 一道题弄明白二维数组的指针