文件IO消耗分析
Linux在操作文件的时候,先将文件放入文件缓存,直到内存不足或者进程使用。这是一种提升IO速度的方式。
1.pidstat
KB_rd/s表示每秒读,KB_wr/s每秒写
2.iostat
查看历史IO
网络IO分析
使用命令 sar -n FULL 1 2
内存消耗分析
JVM内存消耗过多会导致GC喜欢 ii 次难过频繁,CPU消耗增加,应用线程的执行速度严重下降,甚至造成OutOfMemoryError,最终导致Java进程退出。
vmstat
可使用这个命令查看信息和内存相关的主要是memory下的swpd、free、buff、cache以及swap下的si和so。
swpd:虚拟内存已使用的部分
free:空闲的物理内存
buff:用于缓冲的内存
cache:缓存的内存
swap的si:每秒从disk读至内存的数据量
swap的so:每秒从内存中xierudisk的数据量。
swap过高通常是由于物理内存不够用,swap消耗情况主要关注的是swap IO的状况。
Java应用是单进程应用,因此只要JVM的内存设置不是过大,是不会操作到swap区域的。
sar
物理内存相关的信息主要是kbmemfree、kbmemused、%memused、kbbuffers、kbcached。当物理内存有空心啊时,linux会使用一些物理内存用于buffer 以及cache。一提升系统的运行效率;物理内存=kbmemfree+kbbuffers+kbcahched。
vmstat和sar的共同弱点是不能分析进程所占用的内存量。
top
可查看进程所消耗的内存量,看到的是JVM已分配的内存已加上Java应用所消耗的JM以外的物理内存,这会导致top中看到Java所消耗的内存带下可能超过-Xmx机上-XX:MaxPerSize设置内存大小,并且Java程序启动后知识占据-Xms的地址空间,但并没有占据实际的内存,只有在相应的地址空间被使用过后被计入消耗的内存中。很难根据top判断Java进程消耗的内存中有多少是属于JVM,一个小技巧是,对犹豫内存满而发生过Full GC的应用而言,多数情况先,可以认为java进程中显示出来的内存消耗值即为JVM -Xmx的值加上消耗的JVM外的内存值。
pidstat
使用命令 pidstat -r -p
pid
interval
, [times]. 执行命令可查看该进程所占用的物理内存和虚拟内存大小。
对物理内存的消耗
基于Direct BytBuffer可以很容易地实现对物理内存的直接操作,无须耗费JVM Heap区。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 1package cn.edu.hust;
2
3import java.nio.ByteBuffer;
4
5public class JVM1 {
6 public static void main(String[] args) throws InterruptedException {
7 Thread.sleep(20000);
8 System.out.println("read to create bytes, so JVM heap will be used");
9 byte[] bytes=new byte[128*1000*1000];
10 bytes[0]=1;
11 bytes[1]=2;
12 Thread.sleep(10000);
13 System.out.println("read to allocate & put direct bytebuffers,no JVM heap should be used");
14
15 ByteBuffer buffer=ByteBuffer.allocate(128*1024*1024);
16 buffer.put(bytes);
17 buffer.flip();
18 Thread.sleep(10000);
19
20 System.out.println("ready to gc,JVM heap will be freed");
21 bytes=null;
22 System.gc();
23 Thread.sleep(10000);
24 System.out.println("ready to get bytes,then JVM heap will be used");
25
26 byte[] resultBytes=new byte[128*1000*1000];
27 buffer.get(resultBytes);
28 System.out.println("resultBytes[1] is:"+resultBytes[1]);
29 Thread.sleep(10000);
30 System.out.println("ready to gc all");
31 buffer=null;
32 resultBytes=null;
33 System.gc();
34 Thread.sleep(10000);
35 }
36}
37
在IDEA中配置 -Xms140M -Xmx140M参数执行上面的代码可以根据命令查看
基于direct vytebuffer消耗的JVM heap外的物理内存,同样是给予GC方式释放。
对JVM内存的消耗
Java程序出现内存消耗过多、GC频繁或者OutOfmemeroyError情况,要首先分析其耗费的JVM外的物理内存还是JVM heap区。