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

24次阅读

共计 5082 个字符,预计需要花费 13 分钟才能阅读完成。

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…

正文完
 0