前言
前段时间有业务项目提出生产环境有个Java业务实例响应缓慢,想通过分析JVM的线程堆栈等信息定位 问题原因。但是他们使用的Open JDK是只安装了JRE,没有安装JDK的版本,无法使用JVM的一些常用命令。 我们通过在容器内安装并使用jattach工具成功协助项目组定位并解决了问题。本文主要介绍了如何在 容器内安装和使用jattach工具分析JVM运行过程中存在的问题(非容器同样适用)
jattach简介
- 通过动态附加机制向JVM进程发送命令的实用程序。
- 一体化集成jmap + jstack + jcmd + jinfo功能在一起的程序。
- 不需要安装JDK,只需要JRE就能工作,支持Linux容器。
1.容器内安装jattach工具
-
1.1 容器内可访问外网安装jattach工具的方法
通过curl/wget命令下载
curl -O -L https://github.com/jattach/jattach/releases/download/v2.1/jattach chmod +x jattach注意若使用curl命令在此处要加上 -L,否则会因为重定向导致下载文件为空
-
1.2 容器内无法访问外网安装jattach工具的方法
通过kubectl cp或者docker cp 命令,此处为了方便演示使用kubectl cp
例如现在要往grpc-server-556786dcbc-2fnxs这个pod中的container-r1clbo容器里复制jattach工具
chmod +x jattach // 注意此处要先加上执行权限 kubectl cp /Users/apple/Downloads/jattach grpc-server-556786dcbc-2fnxs:/app/jattach -c container-r1clbo -n platform其中:
- /Users/apple/Downloads/jattach 是本地文件路径
- grpc-server-556786dcbc-2fnxs 是pod名称
- /app/jattach 是容器内文件路径
- -c后面的container-r1clbo是容器名称
从本地复制命令如下:
文件复制到容器内结果如下:
2.在容器内使用jattach工具定位JVM问题/调优JVM
- 2.1 jttach命令介绍
| 命令 | 描述 |
|---|---|
| load | 加载agent包 |
| properties | 打印系统属性 |
| agentProperties | 打印agent属性 |
| datadump | 展示堆和线程统计信息 |
| threaddump | 转储当前所有线程的追踪信息(类似 jstack) |
| dumpheap | dump 堆信息 (类似 jmap) |
| inspectheap | 展示堆内存对象的统计信息 (类似 jmap -histo) |
| setflag | 动态调整虚拟机的参数 (类似 jinfo -flag) |
| printflag | 打印虚拟机的参数 (类似 jinfo -flag) |
| jcmd | 执行jcmd命令 |
- 2.2 在容器内实际操作jattach命令
-
2.2.1 properties 打印系统属性
jattach [pid] properties
-
2.2.2 datadump 展示堆和线程统计信息
jattach [pid] datadump
注意: 此命令是将dump所有线程信息和当前堆信息输出到应用的标准输出里了,而不是执行jattach命令所在的终端
执行datadump命令后在应用程序标准输出日志中查看线程dump信息和堆信息如下
-
2.2.3 threaddump 转储当前所有线程的追踪信息
jattach [pid] threaddump
-
2.2.4 dumpheap 展示堆内存对象的统计信息
jattach [pid] dumpheap [fileName]
-
2.2.5 inspectheap 展示堆内存对象的统计信息
jattach [pid] inspectheap
-
2.2.6 printflag 打印虚拟机的参数
jattach [pid] printflag [flagName]
-
2.2.7 setflag 动态调整虚拟机的参数
jattach [pid] setflag [flag,flagValue ...]
比如调整MinHeapFreeRatio
-
2.2.8 jcmd 执行jcmd命令
jattach [pid] jcmd [command]
查看线程信息
查看堆内存信息
-
附录
这是HotSpot Attach API的轻量级版本