关于java:使用top命令分析java程序占用内存

ps aux命令执行后果的几个列的信息的含意

USER    过程所属用户
PID     过程ID 
%CPU    过程占用CPU百分比
%MEM    过程占用内存百分比
VSZ     虚拟内存占用大小 单位:kb(killobytes)
RSS     理论内存占用大小 单位:kb(killobytes)
TTY     终端类型
STAT    过程状态
START   过程启动时刻
TIME    过程运行时长,过程曾经耗费的CPU工夫
COMMAND 启动过程的命令的名称和参数

top 命令 VSZ,RSS,TTY,STAT, VIRT,RES,SHR,DATA的含意

VIRT:virtual memory usage 虚拟内存
1、过程“须要的”虚拟内存大小,包含过程应用的库、代码、数据等
2、如果过程申请100m的内存,但理论只应用了10m,那么它会增长100m,而不是理论的使用量

RES:resident memory usage 常驻内存
1、过程以后应用的内存大小,但不包含swap out
2、蕴含其余过程的共享
3、如果申请100m的内存,理论应用10m,它只增长10m,与VIRT相同
4、对于库占用内存的状况,它只统计加载的库文件所占内存大小

SHR:shared memory 共享内存
1、除了本身过程的共享内存,也包含其余过程的共享内存
2、尽管过程只应用了几个共享库的函数,但它蕴含了整个共享库的大小
3、计算某个过程所占的物理内存大小公式:RES – SHR
4、swap out后,它将会降下来

DATA
1、数据占用的内存。如果top没有显示,按f键能够显示进去。
2、真正的该程序要求的数据空间,是真正在运行中要应用的。

top 运行中能够通过 top 的外部命令对过程的显示方式进行管制。外部命令如下:
s – 扭转画面更新频率
l – 敞开或开启第一局部第一行 top 信息的示意
t – 敞开或开启第一局部第二行 Tasks 和第三行 Cpus 信息的示意
m – 敞开或开启第一局部第四行 Mem 和 第五行 Swap 信息的示意
N – 以 PID 的大小的顺序排列示意过程列表
P – 以 CPU 占用率大小的顺序排列过程列表
M – 以内存占用率大小的顺序排列过程列表
h – 显示帮忙
n – 设置在过程列表所显示过程的数量
q – 退出 top
s – 扭转画面更新周期

序号 列名 含意
a PID 过程id
b PPID 父过程id
c RUSER Real user name
d UID 过程所有者的用户id
e USER 过程所有者的用户名
f GROUP 过程所有者的组名
g TTY 启动过程的终端名。不是从终端启动的过程则显示为 ?
h PR 优先级
i NI nice值。负值示意高优先级,正值示意低优先级
j P 最初应用的CPU,仅在多CPU环境下有意义
k %CPU 上次更新到当初的CPU工夫占用百分比
l TIME 过程应用的CPU工夫总计,单位秒
m TIME+ 过程应用的CPU工夫总计,单位1/100秒
n %MEM 过程应用的物理内存百分比
o VIRT 过程应用的虚拟内存总量,单位kb。VIRT=SWAP+RES
p SWAP 过程应用的虚拟内存中,被换出的大小,单位kb。
q RES 过程应用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
r CODE 可执行代码占用的物理内存大小,单位kb
s DATA 可执行代码以外的局部(数据段+栈)占用的物理内存大小,单位kb
t SHR 共享内存大小,单位kb
u nFLT 页面谬误次数
v nDRT 最初一次写入到当初,被批改过的页面数。
w S 过程状态。(D=不可中断的睡眠状态,R=运行,S=睡眠,T=跟踪/进行,Z=僵尸过程)
x COMMAND 命令名/命令行
y WCHAN 若该过程在睡眠,则显示睡眠中的零碎函数名
z Flags 工作标记,参考 sched.h

默认状况下仅显示比拟重要的 PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND 列。能够通过上面的快捷键来更改显示内容。

通过 f 键能够抉择显示的内容。按 f 键之后会显示列的列表,按 a-z 即可显示或暗藏对应的列,最初按回车键确定。
按 o 键能够扭转列的显示程序。按小写的 a-z 能够将相应的列向右挪动,而大写的 A-Z 能够将相应的列向左挪动。最初按回车键确定。
按大写的 F 或 O 键,而后按 a-z 能够将过程依照相应的列进行排序。而大写的 R 键能够将以后的排序倒转。

jmap命令

jmap -heap 过程ID

Attaching to process ID 17775, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13

using thread-local object allocation.
Parallel GC with 2 thread(s)           parallel并发垃圾回收器

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 1006632960 (960.0MB)  以后JVM最大堆大小
   NewSize                  = 20971520 (20.0MB)
   MaxNewSize               = 335544320 (320.0MB)
   OldSize                  = 41943040 (40.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)  以后元空间大小
   CompressedClassSpaceSize = 1073741824 (1024.0MB)   
   MaxMetaspaceSize         = 17592186044415 MB       元空间最大大小
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 25165824 (24.0MB)
   used     = 15424152 (14.709617614746094MB)
   free     = 9741672 (9.290382385253906MB)
   61.29007339477539% used
From Space:
   capacity = 1572864 (1.5MB)
   used     = 1013016 (0.9660873413085938MB)
   free     = 559848 (0.5339126586914062MB)
   64.40582275390625% used
To Space:
   capacity = 1572864 (1.5MB)
   used     = 0 (0.0MB)
   free     = 1572864 (1.5MB)
   0.0% used
PS Old Generation
   capacity = 84934656 (81.0MB)
   used     = 62824456 (59.91407012939453MB)
   free     = 22110200 (21.08592987060547MB)
   73.96798781406733% used

ps命令

ps -p 过程ID -o vsz,rss

   VSZ   RSS
3701784 413924

VSZ是指已调配的线性空间大小,这个大小通常并不等于程序理论用到的内存大小,产生这个的可能性很多,比方内存映射,共享的动静库,或者向零碎申请了更多的堆,都会扩大线性空间大小。

RSZ是Resident Set Size,常驻内存大小,即过程理论占用的物理内存大小

pmap命令

pmap -x 过程ID
Address           Kbytes     RSS   Dirty Mode   Mapping
0000000000400000       4       4       0 r-x--  java
0000000000600000       4       4       4 rw---  java
00000000017f8000    2256    2136    2136 rw---    [ anon ]
00000000c4000000   82944   63488   63488 rw---    [ anon ]
00000000c9100000  572416       0       0 -----    [ anon ]
00000000ec000000   27648   27136   27136 rw---    [ anon ]
00000000edb00000  300032       0       0 -----    [ anon ]
......
total kB         3701784  413924  400716

Address: 内存调配地址
Kbytes:  理论调配的内存大小
RSS:     程序理论占用的内存大小
Mapping: 调配该内存的模块的名称

anon,这些示意这块内存是由mmap调配的

JAVA利用内存剖析

JAVA过程内存 = JVM过程内存+heap内存+ 永恒代内存+ 本地办法栈内存+线程栈内存 +堆外内存 +socket 缓冲区内存+元空间

linux内存和JAVA堆中的关系

RES = JAVA正在存活的内存对象大小 + 未回收的对象大小 + 其它

VIART= JAVA中申请的内存大小,即 -Xmx -Xms + 其它

其它 = 永恒代内存+ 本地办法栈内存+线程栈内存 +堆外内存 +socket 缓冲区内存 +JVM过程内存

JVM内存模型(1.7与1.8之间的区别)

算一下求和能够得悉前者总共给Java环境调配了128M的内存,而ps输入的VSZ和RSS别离是3615M和404M。
RSZ和理论堆内存占用差了276M,内存组成别离为:

JVM自身须要的内存,包含其加载的第三方库以及这些库调配的内存

NIO的DirectBuffer是调配的native memory

内存映射文件,包含JVM加载的一些JAR和第三方库,以及程序外部用到的。下面 pmap 输入的内容里,有一些动态文件所占用的大小不在Java的heap里

JIT, JVM会将Class编译成native代码,这些内存也不会少,如果应用了Spring的AOP,CGLIB会生成更多的类,JIT的内存开销也会随之变大

JNI,一些JNI接口调用的native库也会调配一些内存,如果遇到JNI库的内存泄露,能够应用valgrind等内存泄露工具来检测

线程栈,每个线程都会有本人的栈空间,如果线程一多,这个的开销就很显著
以后jvm线程数统计:jstack 过程ID |grep ‘tid’|wc –l  (linux 64位零碎中jvm线程默认栈大小为1MB)
ps huH p 过程ID|wc -l   ps -Lf 过程ID | wc -l
top -H -p 过程ID
cat /proc/{pid}/status

jmap/jstack 采样,频繁的采样也会减少内存占用,如果你有服务器衰弱监控,这个频率要管制一下

jstat命令

JVM的几个GC堆和GC的状况,能够用jstat来监控,例如监控某个过程每隔1000毫秒刷新一次,输入20次

jstat -gcutil 过程ID 1000 20

  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00  39.58  95.63  74.66  98.35  96.93    815    4.002     3    0.331    4.333
  0.00  39.58  95.76  74.66  98.35  96.93    815    4.002     3    0.331    4.333
 41.67   0.00   1.62  74.67  98.35  96.93    816    4.006     3    0.331    4.337
 41.67   0.00   1.67  74.67  98.35  96.93    816    4.006     3    0.331    4.337
 41.67   0.00   3.12  74.67  98.35  96.93    816    4.006     3    0.331    4.337
 41.67   0.00   3.12  74.67  98.35  96.93    816    4.006     3    0.331    4.337
 41.67   0.00   8.39  74.67  98.35  96.93    816    4.006     3    0.331    4.337
 41.67   0.00   9.85  74.67  98.35  96.93    816    4.006     3    0.331    4.337
 
S0    年老代中第一个survivor(幸存区)已应用的占以后容量百分比
S1    年老代中第二个survivor(幸存区)已应用的占以后容量百分比
E     年老代中Eden(伊甸园)已应用的占以后容量百分比
O     old代已应用的占以后容量百分比
P     perm代已应用的占以后容量百分比
YGC   从应用程序启动到采样时年老代中gc次数
YGCT  从应用程序启动到采样时年老代中gc所用工夫(s)
FGC   从应用程序启动到采样时old代(全gc)gc次数
FGCT  从应用程序启动到采样时old代(全gc)gc所用工夫(s)
GCT   从应用程序启动到采样时gc用的总工夫(s)

总结

失常状况下jmap输入的内存占用远小于 RSZ,能够不必太放心,除非产生一些严重错误,比方PermGen空间满了导致OutOfMemoryError产生,或者RSZ太高导致引起零碎公愤被OOM Killer给干掉,就得留神了,该加内存加内存,没钱买内存加替换空间,或者按下面列的组成部分逐个排除。

这几个内存指标之间的关系是:VSZ >> RSZ >> Java程序理论应用的堆大小

转载自:https://www.jianshu.com/p/479…

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理