pidstat –p 进程号或者用命令:top –p 进程号
示例:
top –p 10461
说明:
系统运行时间和平均负载:
top - 11:25:12(当前时间) up 28 days, 42 min(系统已运行时间), 13 users(当前登录用户数), load average: 0.98, 1.00, 1.02(5分钟,10分钟,15分钟的负载情况)
任务(进程):
Tasks: 1 total(系统总进程数), 0 running(运行中的进程数), 1 sleeping(休眠中的进程数), 0 stopped(停止的进程数), 0 zombie(僵尸状态的进程数)
CPU状态:
Cpu(s): 0.6%us(运行未调整优先级的)用户进程的CPU的百分比, 0.3%sy(运行内核进程的CPU的百分比), 0.0%ni(运行已调整优先级的用户进程的CPU的百分比), 99.0%id(空闲CPU的百分比), 0.0%wa(用于等待IO完成的CPU的百分比), 0.0%hi(处理硬件中断的CPU的百分比), 0.0%si(处理软件中断的CPU的百分比), 0.0%st(虚拟机占用的百分比)
物理内存使用情况:
Mem: 32837532k total(全部可用内存), 22419516k used(已使用内存), 10418016k free(空闲内存), 49372k buffers(缓冲内存)
虚拟内存(交换空间)使用情况:
Swap: 16490492K total(全部可用内存),0k used(已使用内存), 16490492k free(空闲内存), 423252k cached(缓冲交换空间)
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
10461 tst_cps 20 0 9175m 606m 15m S 0.7 1.9 63:43.53
Java
PID:进程ID,进程的唯一标识符
USER:进程所有者的实际用户名。
PR:进程的调度优先级。这个字段的一些值是’rt’。这意味这这些进程运行在实时态。
NI:进程的nice值(优先级)。越小的值意味着越高的优先级。
VIRT:进程使用的虚拟内存。
RES:驻留内存大小。驻留内存是任务使用的非交换物理内存大小。
SHR:SHR是进程使用的共享内存。
S:这个是进程的状态。它有以下不同的值:D – 不可中断的睡眠态。R – 运行态。S – 睡眠态。T – 被跟踪或已停止。Z – 僵尸态。
%CPU:自从上一次更新时到现在任务所使用的CPU时间百分比。
%MEM:进程使用的可用物理内存百分比。
TIME+:任务启动后到现在所使用的全部CPU时间,精确到百分之一秒。
COMMAND:运行进程所使用的命令。
2. 查看进程内占用cpu和内存最多的线程
ps -Lfp pid或者ps -mp pid -o THREAD, tid, time或者top -Hp pid
示例:
top –Hp 7122
3. 根据线程号打印线程堆栈
jstack 进程号|grep 线程号的十六进制
可以添加“> stack.log”到文件中
示例:
对7147线程号打印堆栈,只取20行查看
[tst_cps@futsthost02 ~]$ jstack 7122|grep 1beb -A 20
"Service Thread" daemon prio=10 tid=0x00007fb8ec112800 nid=0x1beb runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
4. 查找WAITING或者deadlock或者Blocked的线程堆栈
[cps_alarm@rac2 ~]$ jstack 36346|grep "LOCKED" -A 10
[cps_alarm@rac2 ~]$ jstack 36346|grep "deadlock" -A 10
5. 用jstat查看GC和PermGen相关的信息
根据jstat统计的维度不同,可以使用如下表中的选项进行不同维度的统计,不同的操作系统支持的选项可能会不一样,可以通过-options选项,查看不同操作系统所支持选项,如:
Option |
Displays... |
class |
用于查看类加载情况的统计 |
compiler |
用于查看HotSpot中即时编译器编译情况的统计 |
gc |
用于查看JVM中堆的垃圾收集情况的统计 |
gccapacity |
用于查看新生代、老生代及持久代的存储容量情况 |
gccause |
用于查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因。 |
gcnew |
用于查看新生代垃圾收集的情况 |
gcnewcapacity |
用于查看新生代的存储容量情况 |
gcold |
用于查看老生代及持久代发生GC的情况 |
gcoldcapacity |
用于查看老生代的容量 |
gcpermcapacity |
用于查看持久代的容量 |
gcutil |
用于查看新生代、老生代及持代垃圾收集的情况 |
printcompilation |
HotSpot编译方法的统计 |
示例:
[cps_alarm@rac2 ~]$ jstat -class 36346
Loaded Bytes Unloaded Bytes Time
399 788.1 0 0.0 0.05
Loaded:加载的类的数量
Bytes:加载的类的大小,单位为Kb
Unloaded:卸载的类的数量
Bytes:卸载的类的大小,单位为Kb
Time:花在类的加载和卸载的时间
[cps_alarm@rac2 ~]$ jstat -gc 36346
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
32768.0 32768.0 0.0 0.0 196608.0 15729.1 262144.0 0.0 - - - - 0 0.000 0 0.000 0.000
6. 使用jmap统计内存使用情况
导出java程序对象统计信息:
jmap -histo pid > /home/tst_zcgl/2.txt
导出dump文件
jmap -dump:format=b,file=/home/tst_zcgl/3.hprof 3941
示例:
[cps_alarm@rac2 ~]$ jmap -histo 36346
num #instances #bytes class name
----------------------------------------------
1: 8 15642976 [I
2: 5908 761392
3: 5908 676328
4: 399 459152
5: 362 283328
6: 399 273672
7: 1866 202056 [C
8: 1070 156128 [B
9: 461 45224 java.lang.Class
10: 679 43952 [[I
11: 613 37352 [S
12: 1474 35376 java.lang.String
13: 45 24480
14: 333 15624 [Ljava.lang.Object;
15: 119 8568 java.lang.reflect.Field
16: 9 7056
17: 187 5984 java.io.File
7. 使用jinfo命令查看虚拟机配置信息
示例:jinfo pid
8. Jcmd命令-涵盖了jmap,jstack的命令
jcmd的常见用法:
在项目中添加-XX:NativeMemoryTracking=detail
JVM参数重启项目
8.1 列出当前运行的所有的虚拟机
[tst_cps@futsthost02 logs]$ jcmd -l
1254 sun.tools.jcmd.JCmd -l
7122 com.fuiou.cps.StartUp
8.2 列出虚拟机支持的命令
[tst_cps@futsthost02 logs]$ jcmd 7122 help
7122:
The following commands are available:
VM.native_memory
VM.commercial_features
GC.rotate_log
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
Thread.print
GC.class_histogram
GC.heap_dump
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
Help
8.3 统计原生内存
Jcmd显示的内存包括堆内内存、Code区域、通过unsafe.allocateMemory和DirectByteBuffer申请的内存,但是不包含其他Native Code(C代码)申请的堆外内存。
使用jcmd 14184 VM.native_memory detail可以看到内存地址空间。在分析内存泄露时,可能会用到这些地址空间。
[tst_cps@web1 ~]$ jcmd 14184 VM.native_memory
14184:
Native Memory Tracking:
Total: reserved=900950KB(保留内存), committed=787874KB(提交内存)
- Java Heap (reserved=655872KB, committed=590336KB)
(mmap: reserved=655872KB, committed=590336KB)
- Class (reserved=9870KB, committed=9870KB)(用于保存类的元数据的原生内存)
(classes #6732)(6732个类)
(malloc=9870KB, #4219)
- Thread (reserved=118902KB, committed=118902KB)
(thread #115)(115个线程)
(stack: reserved=118220KB, committed=118220KB)
(malloc=365KB, #470)
(arena=317KB, #230)
- Code (reserved=50423KB, committed=3171KB)(JIT代码缓存)
(malloc=503KB, #1422)
(mmap: reserved=49920KB, committed=2668KB)
- GC (reserved=33760KB, committed=33504KB)
(malloc=10384KB, #141)
(mmap: reserved=23376KB, committed=23120KB)
- Compiler (reserved=146KB, committed=146KB)(编译器自身操作使用的内存)
(malloc=48KB, #103)
(arena=98KB, #2)
- Internal (reserved=14214KB, committed=14182KB) (包括了directMemory)
(malloc=14182KB, #2367)
(mmap: reserved=32KB, committed=0KB)
- Symbol (reserved=9771KB, committed=9771KB) (保留字符串的引用和符号表引用)
(malloc=6439KB, #57283)
(arena=3332KB, #1)
- Memory Tracking (reserved=7798KB, committed=7798KB)
(malloc=7798KB, #418)
- Pooled Free Chunks (reserved=194KB, committed=194KB)
(malloc=194KB)
9. Pmap查看进程的内存映射信息
示例:
[cps_alarm@rac2 ~]$ pmap -x 4619|sort -k 3 -n –r(按照Rss降序排列)
total kB 18014124742943900 23444 13584
00007f7bc94dc000 11736 6892 0 r-x-- libjvm.so
00000000d8000000 21504 2452 2452 rw--- [ anon ]
00007f7bb8b92000 2340 2340 2340 rw--- [ anon ]
00007f7bc0987000 1792 1792 0 r--s- rt.jar
00007f7bc1270000 48304 1600 1600 rw--- [ anon ]
00007f7bb8dde000 2044 1044 1044 rw--- [ anon ]
00007f7bc86f0000 1028 1028 1028 rw--- [ anon ]
00007f7bca251000 784 784 784 rw--- libjvm.so
00007f7bca356000 1576 588 0 r-x-- libc-2.12.so
00007f7bc8630000 556 556 556 rw--- [ anon ]
00007f7bc8047000 656 528 528 rw--- [ anon ]
00007f7bc0b47000 1752 472 472 rw--- [ anon ]
00000000e0000000 524288 452 452 rw--- [ anon ]
00007f7b70000000 392 344 344 rw--- [ anon ]
00007f7bc0033000 9552 336 336 rw--- [ anon ]
00007f7bc1000000 2496 256 256 rwx-- [ anon ]
00007f7bca315000 260 188 188 rw--- [ anon ]
00007f7bcae2e000 1032 116 116 rw--- [ anon ]
00007f7bcad20000 128 116 0 r-x-- ld-2.12.so
00007f7bc8c17000 164 112 0 r-x-- libjava.so
00007f7bb97e6000 41064 112 112 rw--- [ anon ]
00007f7bb94e5000 1016 92 92 rw--- [ anon ]
00007f7bb93e4000 1016 92 92 rw--- [ anon ]
找到可疑地址空间:在jcmd 进程号 VM.native_memory detail命令输出的地址空间中查找,如果没有考虑是native code分配地址空间引起。
可参看这篇文字:
https://mp.weixin.qq.com/s/cs92_dRqsn2_jHAtcEB57g
JAVA_HOME=/usr/java/jdk1.7.0_80
OUTPUT_HOME=~/output
DEPLOY_HOME=$1
HOST_NAME=`hostname`
DUMP_PIDS=`ps --no-heading -C java -f --width 1000 | grep "$DEPLOY_HOME" |awk '{print $2}'`
if [ -z "$DUMP_PIDS" ]; then
echo "The server $HOST_NAME is not started!"
exit 1;
fi
if [ ! -d $OUTPUT_HOME ]; then
mkdir $OUTPUT_HOME
fi
DUMP_ROOT=$OUTPUT_HOME/dump
if [ ! -d $DUMP_ROOT ]; then
mkdir $DUMP_ROOT
fi
DUMP_DATE=`date +%Y%m%d%H%M%S`
DUMP_DIR=$DUMP_ROOT/dump-$DUMP_DATE
if [ ! -d $DUMP_DIR ]; then
mkdir $DUMP_DIR
fi
echo -e "Dumping the server $HOST_NAME ...\c"
for PID in $DUMP_PIDS ; do
$JAVA_HOME/bin/jstack $PID > $DUMP_DIR/jstack-$PID.dump 2>&1
echo -e ".\c"
$JAVA_HOME/bin/jinfo $PID > $DUMP_DIR/jinfo-$PID.dump 2>&1
echo -e ".\c"
$JAVA_HOME/bin/jstat -gcutil $PID > $DUMP_DIR/jstat-gcutil-$PID.dump 2>&1
echo -e ".\c"
$JAVA_HOME/bin/jstat -gccapacity $PID > $DUMP_DIR/jstat-gccapacity-$PID.dump 2>&1
echo -e ".\c"
$JAVA_HOME/bin/jmap $PID > $DUMP_DIR/jmap-$PID.dump 2>&1
echo -e ".\c"
$JAVA_HOME/bin/jmap -heap $PID > $DUMP_DIR/jmap-heap-$PID.dump 2>&1
echo -e ".\c"
$JAVA_HOME/bin/jmap -histo $PID > $DUMP_DIR/jmap-histo-$PID.dump 2>&1
echo -e ".\c"
if [ -r /usr/sbin/lsof ]; then
/usr/sbin/lsof -p $PID > $DUMP_DIR/lsof-$PID.dump
echo -e ".\c"
fi
done
if [ -r /usr/bin/sar ]; then
/usr/bin/sar > $DUMP_DIR/sar.dump
echo -e ".\c"
fi
if [ -r /usr/bin/uptime ]; then
/usr/bin/uptime > $DUMP_DIR/uptime.dump
echo -e ".\c"
fi
if [ -r /usr/bin/free ]; then
/usr/bin/free -t > $DUMP_DIR/free.dump
echo -e ".\c"
fi
if [ -r /usr/bin/vmstat ]; then
/usr/bin/vmstat > $DUMP_DIR/vmstat.dump
echo -e ".\c"
fi
if [ -r /usr/bin/mpstat ]; then
/usr/bin/mpstat > $DUMP_DIR/mpstat.dump
echo -e ".\c"
fi
if [ -r /usr/bin/iostat ]; then
/usr/bin/iostat > $DUMP_DIR/iostat.dump
echo -e ".\c"
fi
if [ -r /bin/netstat ]; then
/bin/netstat > $DUMP_DIR/netstat.dump
echo -e ".\c"
fi
echo "OK!"