Java性能调优(二):IO和内存分析

释放双眼,带上耳机,听听看~!

文件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区。

给TA打赏
共{{data.count}}人
人已打赏
安全技术

Bootstrap框架之排版

2021-12-21 16:36:11

安全技术

从零搭建自己的SpringBoot后台框架(二十三)

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索