1、查看哪些应用占用内存比较大:
查看哪几个进程内存占用最高:top -c,输入大写M,以内存使用率从高到低排序
PID : 进程id PPID : 父进程id RUSER : Real user name UID : 进程所有者的用户id USER : 进程所有者的用户名 GROUP : 进程所有者的组名 TTY : 启动进程的终端名。不是从终端启动的进程则显示为 ? PR : 优先级 NI : nice值。负值表示高优先级,正值表示低优先级 P : 最后使用的CPU,仅在多CPU环境下有意义 %CPU : 上次更新到现在的CPU时间占用百分比 TIME : 进程使用的CPU时间总计,单位秒 TIME+ : 进程使用的CPU时间总计,单位1/100秒 %MEM : 进程使用的物理内存百分比 VIRT : 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES SWAP : 进程使用的虚拟内存中,被换出的大小,单位kb。 RES : 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA CODE : 可执行代码占用的物理内存大小,单位kb DATA : 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb SHR : 共享内存大小,单位kb nFLT : 页面错误次数 nDRT : 最后一次写入到现在,被修改过的页面数。 S : 进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程 COMMAND : 命令名/命令行 WCHAN : 若该进程在睡眠,则显示睡眠中的系统函数名 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 键可以将当前的排序倒转
2、通过jmap -heap 进程id 命令排除是由于堆分配内存问题:
Attaching to process ID 542287, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.20-b23 using thread-local object allocation. Garbage-First (G1) GC with 43 thread(s) //堆配置信息 Heap Configuration: //指定 jvm heap 在使用率小于 n 的情况下 ,heap 进行收缩 ,Xmx==Xms 的情况下无效 , 如 MinHeapFreeRatio = 40 //指定 jvm heap 在使用率大于 n 的情况下 ,heap 进行扩张 ,Xmx==Xms 的情况下无效 , 如 MaxHeapFreeRatio = 70 //最大堆空间 MaxHeapSize = 5393874944 (5144.0MB) //设置Yong Generation的初始值大小,一般情况下,不允许-XX:Newratio值小于1,即Old要比Yong大。 NewSize = 1363144 (1.2999954223632812MB) //设置Yong Generation的最大值大小 MaxNewSize = 3235905536 (3086.0MB) OldSize = 5452592 (5.1999969482421875MB) //设置年轻代和老年代的比例,默认情况下,此选项为2 NewRatio = 2 //默认eden空间大小和survivor空间大小的比,默认情况下为8 SurvivorRatio = 8 //初始化元空间大小,控制gc阀值,gc后动态增加或者降低元空间大小,默认情况下平台的不同,步长为12-20M MetaspaceSize = 209715200 (200.0MB) //默认1G,这个参数主要是设置Klass Metaspace的大小,不过这个参数设置了也不一定起作用,前提是能开启压缩指针,假如-Xmx超过了32G,压缩指针是开启不来的。如果有Klass Metaspace,那这块内存是和Heap连着的。 CompressedClassSpaceSize = 1073741824 (1024.0MB) //为类元数据分配的最大空间量 MaxMetaspaceSize = 536870912 (512.0MB) //堆内存中一个Region的大小可以通过-XX:G1HeapRegionSize参数指定,大小区间只能是1M、2M、4M、8M、16M和32M,总之是2的幂次方,如果G1HeapRegionSize为默认值,则在堆初始化时计算Region的实践大小 G1HeapRegionSize = 2097152 (2.0MB) //堆的使用信息 Heap Usage: G1 Heap: //区域数量 regions = 2572 //堆内存大小 capacity = 5393874944 (5144.0MB) //已经使用了 used = 3216639400 (3067.62638092041MB) //空闲着的堆内存 free = 2177235544 (2076.37361907959MB) 59.63503850933923% used 以下同理 G1 Young Generation: Eden Space: regions = 425 capacity = 2650800128 (2528.0MB) used = 891289600 (850.0MB) free = 1759510528 (1678.0MB) 33.62341772151899% used Survivor Space: regions = 1 capacity = 2097152 (2.0MB) used = 2097152 (2.0MB) free = 0 (0.0MB) 100.0% used G1 Old Generation: regions = 1109 capacity = 2740977664 (2614.0MB) used = 2323252648 (2215.62638092041MB) free = 417725016 (398.37361907958984MB) 84.75999927009985% used 35394 interned Strings occupying 3871104 bytes.
3、找到最耗内存的对象
jmap -histo 进程ID(带上:live则表示先进行一次FGC再统计,如jmap -histo:live 进程ID)
4、导出内存转储快照dump文件:
4.1、通过java进程命令定位 系统进程并使用jmap工具dump文件。
ps -ef | grep java
生成dump文件的命令:
jmap -dump:format=b,file=20181218.dump 16048
file后面的是自定义的文件名,最后的数字是进程的pid。
1
2
3
4
4.2、使用jvisualvm来分析dump文件:
4.5、线程当前的状态是我们主要关注的内容。
dump文件中描述的线程状态
runnable:运行中状态,在虚拟机内部执行,可能已经获取到了锁,可以观察是否有locked字样。
blocked:被阻塞并等待锁的释放。
wating:处于等待状态,等待特定的操作被唤醒,一般停留在park(), wait(), sleep(),join() 等语句里。
time_wating:有时限的等待另一个线程的特定操作。
terminated:线程已经退出
4.6、进程的区域划分
进入区(Entry Set):等待获取对象锁,一旦对象锁释放,立即参与竞争。
拥有区(The Owner):已经获取到锁。
等待区(Wait Set):表示线程通过wait方法释放了对象锁,并在等待区等待被唤醒。
4.7、方法调用修饰
locked: 成功获取锁
waiting to lock:还未获取到锁,在进入去等待;
waiting on:获取到锁之后,又释放锁,在等待区等待;
4.8、OQL(对象查询语言)
如果需要根据某些条件来过滤或查询堆的对象,比如现在我们查询下系统中类加载器一共有几种?
8、.用jstack查看一下
jstack pid | grep tid(线程ID) -A 30