Java线上程序频繁JVM FGC问题排障与启示
线上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问题排障与启示相关推荐
- 【深入理解JVM】JAVA线上故障排查全套路
线上故障主要会包括cpu.磁盘.内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍.同时例如jstack.jmap等工具也是不囿于一个方面的问题的,基 ...
- linux 内存溢出排查_记一次JAVA 线上故障排查完整套路
JAVA线上故障排查全套路 线上故障主要会包括cpu.磁盘.内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍.同时例如jstack.jmap等工具也 ...
- Java线上问题排查思路及Linux常用问题分析命令学习
前言 之前线上有过一两次OOM的问题,但是每次定位问题都有点手足无措的感觉,刚好利用星期天,以测试环境为模版来学习一下Linux常用的几个排查问题的命令. 也可以帮助自己在以后的工作中快速的排查线上问 ...
- Java 线上问题排查思路与工具使用
本文来自作者 蓬蒿 在 GitChat 上分享 「Java 线上问题排查思路与工具使用」,「阅读原文」查看交流实录. 「文末高能」 编辑 | 哈比 一.前言 Java 语言是当前互联网应用最为广泛的语 ...
- JAVA线上问题排查及常用命令
前言 线上问题排查是程序员绕不开路.线上故障主要会包括 CPU.磁盘.内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍.同时例如 jstack.jm ...
- 老九java线上_java应用监测(4)-线上问题排查套路
tags: java, troubleshooting, monitor 一句话概括:java应用线上问题如CPU过高,内存溢出,IO过高等问题如何排查,本文为你详细讲述. 1 引言 java应用上线 ...
- java线上问题定位_java定位线上问题
3.jstack: Java 提供的命令.可以查看某个进程的当前线程栈运行情况.根据 这个命令的输出可以定位某个进程的所有线程的当前运行状态.运行代码,以及 是否死锁等等...... A.//int ...
- Arthas - Java 线上问题定位处理的终极利器
前言 在使用 Arthas 之前,当遇到 Java 线上问题时,如 CPU 飙升.负载突高.内存溢出等问题,你需要查命令,查网络,然后 jps.jstack.jmap.jhat.jstat.hprof ...
- 线上FullGC频繁的排查
线上FullGC频繁的排查 问题 前段时间发现线上的一个dubbo服务Full GC比较频繁,大约每两天就会执行一次Full GC. Full GC的原因 我们知道Full GC的触发条件大致情况有以 ...
最新文章
- 机器学习笔试题精选(四)
- ListView 排序
- 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员赋值及源码分析 )
- 域滤波:方框、高斯、中值、双边滤波
- 基于TextRank的关键词提取算法
- Scala与Java差异(四)之数组操作
- 1 MM配置-企业结构-定义-定义评估级别
- JavaScript变量作用域如何像多个级别的政府一样
- linux下RTNETLINK answers: File exists的解决方案
- switchhosts使用
- 第二届上汽零束SOA平台开发者大会揭幕,智能汽车生态加速落地
- 方舟非主机服务器无限距离,方舟生存进化怎么调主机距离
- 【高项】沟通管理(ITTO)
- 在 Windows 系统下常用的 bat 脚本分享
- 高丽参的作用与功效及忌讳
- 如何在Ubuntu下为SI安装Fixedsys字体
- openfeign调用异常:feign.FeignException: [405] during [GET]
- ora-01237 ora-01110 ora-17505 ora-15041
- UCloud邱模炯:为什么内核是云平台稳定性的关键
- YOLO系列目标检测算法-YOLOv6
热门文章
- rust腐蚀 木制窗户怎么修_装修窗帘怎么选最划算?记住这3点,至少能省大几千...
- java intent 传递集合对象_Intent之对象传递(Parcelable传递对象和对象集合)
- fork() || fork() || fork() 与 fork() fork() fork()
- Linxu终端gcc与gcc -c的区别
- delphi socket 流的使用_基于TCP协议的Socket编程和通信_单向通信
- Python Qt GUI设计:QMdiArea和QMdiSubWindow类实现多文档界面(拓展篇—3)
- Python图像拼接:创建全景图
- android组件什么时候加载到r文件,Android自定义加载loading view动画组件
- USTC并行计算复习
- 一道题弄明白二维数组的指针