JVM调优几款好用的内存分析工具

2023-11-10

对于高并发访问量的电商、物联网、金融、社交等系统来说,JVM内存优化是非常有必要的,可以提高系统的吞吐量和性能。通常调优的首选方式是减少FGC次数或者FGC时间,以避免系统过多地暂停。FGC达到理想值后,比如一天或者两天触发一次FGC。FCT时间优化为100~300毫秒后,再减少YoungGC次数或者YoungGC时间,YoungGC仍然会消耗CPU资源,优化YoungGC调用次数和消耗的CPU资源,可以提高系统的吞吐量。

优化GC前,必须获取GC的实际使用情况,最好的方式是通过CG Log收集垃圾回收日志,通过一些可视化工具查看垃圾回收分析数据,比如GCEasy。持续优化和对比优化前后的GC Log,能确认吞吐量和性能是否得到提升。

下面推荐几个常用的内存分析命令和工具

jstat命令

JDK自带的jstat命令用于查看虚拟机垃圾回收的情况,如下命令使用gcutil参数输出堆内存使用情况统计:

jstat –gcutil  -h 20 pid 1000 100

此命令显示进程为pid的内存使用汇总,1000毫秒输出一次,总共输出100行。-h 20表示每20行输出一次表头。-gcutil表示显示JVM内存使用汇总统计:

列表显示了虚拟机各个代的使用情况,描述了堆内存的使用占比和垃圾回收次数,以及占用时间,具体含义如下: 

  • S0,第一个幸存区使用比值。

  • S1,第二个幸存区的使用率。

  • E,伊甸园区的使用比值。

  • O,老年代。

  • M,方法区、元空间使用率。

  • CCS,压缩使用比值。

  • YGC,年轻代垃圾回收次数。

  • YGCT,年轻带垃圾回收占用时间。

  • FGC,全局垃圾回收次数,这对性能影响至关重要。

  • FGCT,全局垃圾回收的消耗时间。

  • GCT,总的垃圾回收时间。

可以看到S0、S1、E变化频率高,说明程序在频繁创建生命周期短的对象,FGC为0,表示还未做过全局垃圾回收。如果FGC变化频率很高,则说明系统性能和吞吐量将下降,或者可能出现内存溢出。

其他查看汇总信息的常用选项如下:

  • -gc,类似gcutil,gcutil以百分比形式显示内存的使用情况,gc显示的是内存占用的字节数,以KB的形式输出堆内存的使用情况。

  • -gccause,类似gcutil,额外输出GC的原因。

jmap命令

jmap命令用于保存虚拟机内存镜像到文件中,然后可以使用JVisualVM或者MAT工具进行进一步分析。命令如下:

jmap -dump:format=b,file=filename.hprof pid

需要注意,实际系统会有2GB到8GB内存,此命令会导致虚拟机暂停工作1~3秒。还有一种是被动获取方式,当虚拟机出现内存溢出的时候,会主动“dump”内存文件。添加虚拟机启动参数:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof

当虚拟机判断达到内存溢出触发条件的时候,会有如下输出并保存镜像文件:

java.lang.OutOfMemoryError: Java heap spaceDumping heap to heapdump.hprof ...

当获得镜像文件后,打开JvisualVM工具,选择菜单“File”,点击装入,选择我们保存过的dump文件,这时面板会打开内存镜像文件。打开较大的内存镜像文件需要较长的时间,需要耐心等候,其他工具,如MAT,或者商业的YourKit Java Profiler打开镜像文件更快,分析功能更强大。

GCeasy

GCeasy是一个分析GC日志文件的在线网站,能根据上传的GC日志,以图表形式显示GC回收过程和统计数据。下图显示的是GC性能的统计情况,如吞吐量显示为99.935%,说明只有少量CPU资源用于垃圾回收。最长的GC时间是20毫秒,属于正常范围。在测试JVM参数调整是否能增加吞吐量,减小垃圾回收占用的CPU时,可以使用这个统计功能。

下图统计了GC总的时间和回收的字节数,也显示了Full GC的统计情况。

JMC

Java Mission Control简称JMC,是JDK自带的工具,是一个高性能的对象监视、管理、产生时间分析和诊断的工具套件,笔者主要用来追踪热点代码与热点线程,是主要的内存优化调优工具。

类似JVisualVM,通过JMX连接进入JMC控制台。

通过连接到远程JVM进程后,可以执行飞行记录(FlightRecord),选择飞行记录存放的路径与执行时间即可,如下图所示。需要注意的是,执行飞行记录功能时会对当前JVM进程有一定的性能影响(大约为5%~10%),所以建议JMC连接隔离环境中的服务器并执行飞行记录功能。

通过一段时间的记录,飞行记录可以反映线程的繁忙程度,以及CPU的热点方法。

使用热点方法可以直接找到最耗时的几个方法,对热点方法重点优化就可以使CPU的使用率下降一大截。

飞行记录还可以反映内存增长的热点方法,以及显示单位时间内创建的最多对象的方法。下图为找到的内存对象中创建的最多的char[]的方法,一个是Fastjson,另一个是Kryo。

小结:通过JMC的热点方法的统计结果可以有针对性地进行优化,笔者通过对线上系统进行优化使得CPU使用率下降了40%、内存GC频率下降了100%以上。

MAT

MAT是Memory Analyzer的简称,它是一款功能强大的Java堆内存分析器,可以分析具有数亿个对象的内存镜像,快速计算对象大小,自动找到嫌疑的泄漏对象并形成内存泄漏报告。MAT是基于Eclipse开发的,是一款免费的内存镜像分析工具,是笔者发现内存泄漏原因的主要工具。

通过File-Open Heap Dump可以打开内存镜像文件,显示内容如下图所示。

它提供了Leak Suspects 报告,输出有可能发生内存泄漏的对象。

OQL

OQL语句类似SQL语句,可以在VisualVM、MAT等大多数内存镜像分析工具中执行,完成对象查找任务。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM调优几款好用的内存分析工具 的相关文章

  • 如何循环遍历所有组合,例如48 选择 5 [重复]

    这个问题在这里已经有答案了 可能的重复 如何在java中从大小为n的集合中迭代生成k个元素子集 https stackoverflow com questions 4504974 how to iteratively generate k
  • HSQL - 识别打开连接的数量

    我正在使用嵌入式 HSQL 数据库服务器 有什么方法可以识别活动打开连接的数量吗 Yes SELECT COUNT FROM INFORMATION SCHEMA SYSTEM SESSIONS
  • 在 Jar 文件中运行 ANT build.xml 文件

    我需要使用存储在 jar 文件中的 build xml 文件运行 ANT 构建 该 jar 文件在类路径中可用 是否可以在不分解 jar 文件并将 build xml 保存到本地目录的情况下做到这一点 如果是的话我该怎么办呢 Update
  • Java 公历日历更改时区

    我正在尝试设置 HOUR OF DAY 字段并更改 GregorianCalendar 日期对象的时区 GregorianCalendar date new GregorianCalendar TimeZone getTimeZone GM
  • 没有 Spring 的自定义 Prometheus 指标

    我需要为 Web 应用程序提供自定义指标 问题是我不能使用 Spring 但我必须使用 jax rs 端点 要求非常简单 想象一下 您有一个包含键值对的映射 其中键是指标名称 值是一个简单的整数 它是一个计数器 代码会是这样的 public
  • 检测并缩短字符串中的所有网址

    假设我有一条字符串消息 您应该将 file zip 上传到http google com extremelylonglink zip http google com extremelylonglink zip not https stack
  • 帮助将图像从 Servlet 获取到 JSP 页面 [重复]

    这个问题在这里已经有答案了 我目前必须生成一个显示字符串文本的图像 我需要在 Servlet 上制作此图像 然后以某种方式将图像传递到 JSP 页面 以便它可以显示它 我试图避免保存图像 而是以某种方式将图像流式传输到 JSP 自从我开始寻
  • 如何在用户输入数据后重新运行java代码

    嘿 我有一个基本的java 应用程序 显示人们是成年人还是青少年等 我从java开始 在用户输入年龄和字符串后我找不到如何制作它它们被归类为 我希望它重新运行整个过程 以便其他人可以尝试 的节目 我一直在考虑做一个循环 但这对我来说没有用
  • tomcat 中受密码保护的应用程序

    我正在使用 JSP Servlet 开发一个Web应用程序 并且我使用了Tomcat 7 0 33 as a web container 所以我的要求是tomcat中的每个应用程序都会password像受保护的manager applica
  • Eclipse 选项卡宽度不变

    我浏览了一些与此相关的帖子 但它们似乎并不能帮助我解决我的问题 我有一个项目 其中 java 文件以 2 个空格的宽度缩进 我想将所有内容更改为 4 空格宽度 我尝试了 正确的缩进 选项 但当我将几行修改为 4 空格缩进时 它只是将所有内容
  • 不接受任何内容也不返回任何内容的函数接口[重复]

    这个问题在这里已经有答案了 JDK中是否有一个标准的函数式接口 不接受也不返回任何内容 我找不到一个 像下面这样 FunctionalInterface interface Action void execute 可运行怎么样 Functi
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 关键字“table”附近的语法不正确,无法提取结果集

    我使用 SQL Server 创建了一个项目 其中包含以下文件 UserDAO java public class UserDAO private static SessionFactory sessionFactory static se
  • 最新的 Hibernate 和 Derby:无法建立 JDBC 连接

    我正在尝试创建一个使用 Hibernate 连接到 Derby 数据库的准系统项目 我正在使用 Hibernate 和 Derby 的最新版本 但我得到的是通用的Unable to make JDBC Connection error 这是
  • Android:无法使用 DbHelper 和 Contract 类将数据插入 SQLite

    public class Main2Activity extends AppCompatActivity private EditText editText1 editText2 editText3 editText4 private Bu
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • 如何使用mockito模拟构建器

    我有一个建造者 class Builder private String name private String address public Builder setName String name this name name retur
  • 使用 svn 1.8.x、subclise 1.10 的 m2e-subclipse 连接器在哪里?

    我读到 m2e 的生产商已经停止生产 svn 1 7 以外的任何版本的 m2e 连接器 Tigris 显然已经填补了维护 m2e subclipse 连接器的空缺 Q1 我的问题是 使用 svn 1 8 x 的 eclipse 更新 url
  • 如何防止在Spring Boot单元测试中执行import.sql

    我的类路径中有一个 import sql 文件 其中包含一些 INSERT 语句 当使用 profile devel 运行我的应用程序时 它的数据被加载到 postgres 数据库中 到目前为止一切正常 当使用测试配置文件执行测试时 imp
  • Spring Rest 和 Jsonp

    我正在尝试让我的 Spring Rest 控制器返回jsonp但我没有快乐 如果我想返回 json 但我有返回的要求 完全相同的代码可以正常工作jsonp我添加了一个转换器 我在网上找到了用于执行 jsonp 转换的源代码 我正在使用 Sp

随机推荐

  • RC电路(一):微分

    1 充放电时间常数 在模拟 数字电路中 常常用到由电阻 和电容 组成的 电路 和 的取值不同 会导致输出波形和输入波形之间的关系也不同 由此也会产生不同的应用 当 时 电容电压 0 63E 当 时 电容电压 0 86E 当 时 电容电压 0
  • 通用嵌入式系统测试平台 ETest简介

    通用嵌入式系统自动化测试平台 通用嵌入式系统测试平台 Embedded System Interface Test Studio 简称 ETest 是针对嵌入式系统进行实时 闭环 非侵入式测试的自动化测试平台 适用于嵌入式系统在设计 仿真
  • 《阵列信号处理及MATLAB实现》绪论、矩阵代数相关内容总结笔记

    第一章 绪论 1 1 研究背景 1 1 1 阵列信号处理简介 将一组传感器按照一定方式布置在空间的不同位置 形成传感器阵列 用传感器阵列来接收空间信号 相当于对空间分布的场信号采样 得到信号源的空间离散观测数据 通过对阵列接受的信号进行处理
  • Lex和Yacc应用方法(一).初识Lex

    Lex和Yacc应用方法 一 初识Lex 草木瓜 20070301 Lex Lexical Analyzar 词法分析生成器 Yacc Yet Another Compiler Compiler编译器代码生成器 是Unix下十分重要的词法分
  • Feign的使用

    基于Feign远程调用 Feign说明 Feign是一个声明式的http客户端 其作用是帮助我们优雅的实现http请求的发送 官网地址 https github com OpenFeign feign Feign的使用 修改服务的pom x
  • MVC中的项目案例

    我们先一起来看看超期的效果图吧 以上就是超期的效果图 我来解析一下 超期操作的模态窗体弹出的条件与归还一样 应选择需要超期的书籍 再弹出模态窗体 模态窗体弹出 数据自动回填上去 罚款金额 超期天数 0 2 获取当前时间为罚款时间 罚款成功后
  • 解决python3在import cv2时报错问题

    在安装了ros 在import cv2时会报错 如下 import cv2 ImportError opt ros kinetic lib python2 7 dist packages cv2 so undefined symbol Py
  • CMake(七):函数和宏

    回顾到目前为止涉及的材料 CMake的语法已经开始看起来很像一门编程语言 它支持变量 if then else逻辑 循环和包含要处理的其他文件 毫无疑问 CMake还支持常用的函数和宏编程概念 就像它们在其他编程语言中的角色一样 函数和宏是
  • vistual studio 2017中导入pthread.h的配置方法

    1 下载pthread h的相关库文件 下载路径 https www mirrorservice org sites sourceware org pub pthreads win32 pthreads w32 2 9 1 release
  • 从技术小白到编程大神的技术书籍推荐

    本人算不上大神 也非计算机专业出身 本着一股热爱技术的精神 研究过各种计算机技术 对于知识的索取方式 比较习惯看书 当然 随着认识的加深 以及新技术的层出不穷 也常接触各种技术文档 早些时候阅读过很多不错的计算机书籍 对于计算机底层的深入认
  • spring boot 提示:程序包不存在,解决方法总结

    背景 之前出现过这样的问题 打包安装父项目就好了 今天改了一下代码 重新编译的时候 又出现了这样的情况 决定深度挖掘一下这里面的问题 spring boot 提示 程序包不存在 解决方法总结 spring boot 提示 程序包不存在 解决
  • Mysql系列(四)彻底理解MVCC+行锁+表锁+间隙锁

    文章目录 一 什么是MVCC 二 什么是行锁 表锁 间隙锁 三 MVCC与各种锁的关系 四 MVCC的实现原理 4 1 多版本 4 2 undo log 4 2 readview 一 什么是MVCC MVCC Multi Version C
  • Unity3D Shader 学习 1

    1 属性定义 用来指定这段代码将有哪些输入 1 name display name Range min max number 定义浮点数范围属性 2 name display name Color number number number
  • 【stm32学习】GPIO函数理解

    注 在魔术棒output选中 下图 函数编译后 可以在声明处右击 跳转至函数的定义 GPIO Init初始化 例子 注意 速度只有三个可选 输入输出模式 GPIO Mode AIN 模拟输入 GPIO Mode IN FLOATING 浮空
  • 【面试系列】JDK动态代理和CGLIB静态代理

    文章目录 前言 JDK动态代理代码实例 Cglib 代理代码实例 两者优缺点 前言 是否在面试过程中经常被问到Spring的代理的问题 比如说几种代理方式 两种代理方式的区别 或者问为什么JDK动态代理只能代理接口 如果你能回答出来JDK动
  • App内测神器之蒲公英--类似 testFlight fir.im

    一 前言部分 没发现蒲公英之前一直采用非常傻B的方式给公司App做内部测试 要么发个测试包让公司测试人员用iTUnes 自己安装 要么苦逼的一个个在我Xcode上直接安装测试包 操作起来又麻烦又苦逼 后来偶然发现了蒲公英感觉这货还真不是一般
  • 《TCP/IP详解卷一:协议》学习笔记八

    一 Traceroute程序的操作 1 Traceroute程序可以让我们看到IP数据报从一台主机传到另一台主机所经过的路由 其还可以让我们使用IP源路由选项 2 为什么不使用IP记录路由选项 RR 而另外开发一个新的应用程序 1 原先并不
  • 机器学习——KNN算法(K最近邻分类算法)(2020最新版)

    1 KNN的例子 转换为坐标 红色是爱情片 蓝色是动作片 黑色是需要判断的点 1 1 KNN具体的做法 其中 欧式距离 欧几里得距离 的计算方法 2 KNN的缺点 3 KNN的实现 coding utf 8 FileName knn alg
  • 静态联编与动态联编

    联编是指一个程序模块 代码之间相互关联的过程 静态联编 是程序的匹配 链接在编译阶段实现 也称早期匹配 重载函数就使用静态联编 编译的阶段 动态联编是指程序联编推迟到运行时候进行 又称晚期匹配 switch if语句就是动态联编的例子 执行
  • JVM调优几款好用的内存分析工具

    对于高并发访问量的电商 物联网 金融 社交等系统来说 JVM内存优化是非常有必要的 可以提高系统的吞吐量和性能 通常调优的首选方式是减少FGC次数或者FGC时间 以避免系统过多地暂停 FGC达到理想值后 比如一天或者两天触发一次FGC FC