一、工具
1.jps -l 查看进程号
2. jinfo 用来查看正在运行的 java 应用程序的扩展参数,包括Java System属性和JVM命令行参数
-
查看java应用启动时候的堆大小
jinfo -flag InitialHeapSize 7661(进程ID)
- 查看java应用最大堆内存大小
jinfo -flag MaxHeapSize 31883
- 查看java应用每线程内存大小
jinfo -flag ThreadStackSize 31883
- 查看java应用所有扩展参数
jinfo -flags 31883
补充:ThreadStackSize、InitialHeapSize 这些参数可用通过下面命令查询
java -XX:+PrintFlagsFinal -version
3. jstat 统计虚拟机信息
- jstat -class 31883
- jstat -compiler 31883
- jstat -gc 31883
4.top命令查看操作系统资源概况和进程信息
top命令返回的视图包含2部分,操作系统资源概况和进程信息
1.1系统运行时间和平均负载
1.操作系统当前时间。
2.up操作系统开机运行时间。
3.user 当前系统登录用户数
4.load average 1s 5s 15s
1.2Task
1.total 系统总进程数
2.running 运行中的进程数
3.sleeping 休眠的进程数
1.3cpu
us代表用户进程占用cpu时间百分比
sy:系统占用cpu 时间百分比
ni:用户空间内改变过优先级的进程占cpu的时间百分比
id:空闲时间占用cpu的百分比
wa:io等待占用cpu的百分比
hi:cpu硬件中断百分比
si:cpu软件中断百分比
st:这个虚拟机被hypervisor偷去的CPU时间
1.4内存使用
内存显示
total:内存总量
used:已使用
free:空闲内存量
buffers:缓存内存量
swap交换分区
total:交换区总量
used:已使用交换总量
free:空闲交换区总量
cached:缓冲的交换区总量
1.5进程状态
pid:进程ID
user:进程所属用户
PR:进程调度的优先级
NI:进程的nice值,值越小优先级越高。
VIRT:进程使用的虚拟内存
RES:驻留内存大小。驻留内存是任务使用的非交换物理内存大小。
SHR:SHR是进程使用的共享内存。共享内存大小,单位kb
S:进程状态
%CPU:自上一次更新到现在任务占用cpu百分比
%MEM:进程占用内存百分百
TIME+进程:任务启动后到现在所使用的全部CPU时间,精确到百分之一秒。
COMMAND:运行进程所使用的命令
5.可视化工具:VisualVM 、MAT
二、案例
CPU 过高:
1.代码
public class CPUTest {
public static void main(String[] args) {
while(true){
}
}
}
2.nohup java -classpath . CPUTest>./a.log 2>&1 &
3.top 获取CPU百分百的PID
4.通过jstack获取指定进程14827的线程的信息,输出至文件
jstack 14827 >/tmp/ana.log
5.查看指定CPU过高的线程id,可以通过crontrol+h, 或者top -H -p 14827
6.线程id14828转16进制39ec, 然后在/tmp/ana.log 文件中搜索39ec,匹配结果如图:
红圈定位到造成cpu 100% 代码
内存溢出
1.代码
import java.util.ArrayList;
import java.util.List;
public class MemOutErrorTest {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();;
while(true){
list.add("web.sendcloud.net");
}
}
}
2.执行
java -Xms20m -Xmx20m -classpath . MemOutErrorTest
3.获取内存的镜像文件两种方式
- 启动进程时候指定参数 java -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ -classpath . MemOutErrorTest
- jmap -dump:format=b,file=java_pid16501.hprof 16501
4.安装eclipse插件Memory Analyzer ,参考:https://www.cnblogs.com/letcafe/p/mat.html
5.打开eclipse-->window-->Open Perspective->Memory Analyzer
6.导入镜像文件 java_pid16501.hprof 查找
企业中遇到过真实的案例
1.spring quartz 做定时任务服务,突然定时任务都不执行了,通过jstack分析,得出该服务有一个任务比较耗时,在本次调度的时间之内未完成任务,造成quarz的线程都被该类任务占满,其他任务出现等待线程池资源的释放。
2.apache poi针对excel文件处理出现内存泄露问题,造成进程宕掉。通过VisualVM远程跟踪解决
解决步骤
1.服务是jetty应用,线上启动时候加参数
参数说明:
Dcom.sun.management.jmxremote添加一个jmx远程连接属性
-Dcom.sun.management.jmxremote.port=1099 指定连接的端口号
-Dcom.sun.management.jmxremote.authenticate=false 是否启用验证
-Dcom.sun.management.jmxremote.ssl=false 是否启用ssl
Djava.net.preferIPv4Stack=true 是否优先使用ipv4
-Djava.rmi.server.hostname=xx.xx.xx.xx 指定远程主机的ip地址
2.jvisualVM 客户端配置JMX
- 添加远程主机
- 添加远程JMX
3.连接成功,分析jvm使用内存情况(配合应用端日志分析泄露问题)