java mmap写文件,2021-2-25:对于 Java MMAP,如何查看文件映射脏页,如何统计MMAP的内存大小?...

我们写一个测试程序:

public static void main(String[] args) throws Exception {

RandomAccessFile randomAccessFile = new RandomAccessFile("./FileMmapTest.txt", "rw");

FileChannel channel = randomAccessFile.getChannel();

MappedByteBuffer []mappedByteBuffers = new MappedByteBuffer[5];

//开5个相同文件的MappedByteBuffer,但是实际机器内存只有8G

mappedByteBuffers[0] = channel.map(FileChannel.MapMode.READ_WRITE, 0, 2 * 1024 * 1024 * 1024 - 1);

mappedByteBuffers[1] = channel.map(FileChannel.MapMode.READ_WRITE, 0, 2 * 1024 * 1024 * 1024 - 1);

mappedByteBuffers[2] = channel.map(FileChannel.MapMode.READ_WRITE, 0, 2 * 1024 * 1024 * 1024 - 1);

mappedByteBuffers[3] = channel.map(FileChannel.MapMode.READ_WRITE, 0, 2 * 1024 * 1024 * 1024 - 1);

mappedByteBuffers[4] = channel.map(FileChannel.MapMode.READ_WRITE, 0, 2 * 1024 * 1024 * 1024 - 1);

for (int j = 0; j < 2*1024*1024*1024 - 1; j++) {

mappedByteBuffers[0].put("a".getBytes());

}

TimeUnit.SECONDS.sleep(1);

byte []to = new byte[1];

for (int j = 0; j < 2*1024*1024*1024 - 1; j++) {

mappedByteBuffers[1].get(to);

mappedByteBuffers[2].get(to);

mappedByteBuffers[3].get(to);

mappedByteBuffers[4].get(to);

}

while(true) {

TimeUnit.SECONDS.sleep(1);

}

}

等到程序运行到最后的死循环的时候,我们来看top -c的结果:

KiB Mem : 7493092 total, 147876 free, 3891680 used, 3453536 buff/cache

KiB Swap: 0 total, 0 free, 0 used. 2845100 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+

25458 zhangha+ 20 0 14.147g 8.840g 8.599g S 0.0 124 2:33.16 java

可以观察到非常有意思的现象,这个进程占用了124%的内存,实际上Swap为0。总占用也没到100%。这是为什么呢?

我们来看下这个进程的smaps文件,这里进程号是25485,我们映射的文件是FileMmapTest.txt:

$ grep -A 11 FileMmapTest.txt /proc/25458/smaps

7fa870000000-7fa8f0000000 rw-s 00000000 ca:01 25190272 /home/zhanghaoxin/FileMmapTest.txt

Size: 2097152 kB

Rss: 2097152 kB

Pss: 493463 kB

Shared_Clean: 2097152 kB

Shared_Dirty: 0 kB

Private_Clean: 0 kB

Private_Dirty: 0 kB

Referenced: 2014104 kB

Anonymous: 0 kB

AnonHugePages: 0 kB

Swap: 0 kB

--

7fa8f0000000-7fa970000000 rw-s 00000000 ca:01 25190272 /home/zhanghaoxin/FileMmapTest.txt

Size: 2097152 kB

Rss: 2097152 kB

Pss: 493463 kB

Shared_Clean: 2097152 kB

Shared_Dirty: 0 kB

Private_Clean: 0 kB

Private_Dirty: 0 kB

Referenced: 2014104 kB

Anonymous: 0 kB

AnonHugePages: 0 kB

Swap: 0 kB

--

7fa970000000-7fa9f0000000 rw-s 00000000 ca:01 25190272 /home/zhanghaoxin/FileMmapTest.txt

Size: 2097152 kB

Rss: 2097152 kB

Pss: 493463 kB

Shared_Clean: 2097152 kB

Shared_Dirty: 0 kB

Private_Clean: 0 kB

Private_Dirty: 0 kB

Referenced: 2014104 kB

Anonymous: 0 kB

AnonHugePages: 0 kB

Swap: 0 kB

--

7fa9f0000000-7faa70000000 rw-s 00000000 ca:01 25190272 /home/zhanghaoxin/FileMmapTest.txt

Size: 2097152 kB

Rss: 2097152 kB

Pss: 493463 kB

Shared_Clean: 2097152 kB

Shared_Dirty: 0 kB

Private_Clean: 0 kB

Private_Dirty: 0 kB

Referenced: 2014104 kB

Anonymous: 0 kB

AnonHugePages: 0 kB

Swap: 0 kB

--

7faa70000000-7faaf0000000 rw-s 00000000 ca:01 25190272 /home/zhanghaoxin/FileMmapTest.txt

Size: 2097152 kB

Rss: 616496 kB

Pss: 123299 kB

Shared_Clean: 616496 kB

Shared_Dirty: 0 kB

Private_Clean: 0 kB

Private_Dirty: 0 kB

Referenced: 616492 kB

Anonymous: 0 kB

AnonHugePages: 0 kB

Swap: 0 kB

其中比较重要的8个字段的含义分别如下:

Size:表示该映射区域在虚拟内存空间中的大小。

Rss:表示该映射区域当前在物理内存中占用了多少空间

Pss:该虚拟内存区域平摊计算后使用的物理内存大小(有些内存会和其他进程共享,例如mmap进来的)。比如该区域所映射的物理内存部分同时也被另一个进程映射了,且该部分物理内存的大小为1000KB,那么该进程分摊其中一半的内存,即Pss=500KB。

Shared_Clean:和其他进程共享的未被改写的page的大小

Shared_Dirty:和其他进程共享的被改写的page的大小

Private_Clean:未被改写的私有页面的大小。

Private_Dirty:已被改写的私有页面的大小。

Swap:表示非mmap内存(也叫anonymous memory,比如malloc动态分配出来的内存)由于物理内存不足被swap到交换空间的大小。

我们可以看到,把这五个MappedByteBuffer的Pss加起来正好是2097151,就是我们映射的大小。可以推断出,我们这五个MappedByteBuffer在linux中的实现就是对应同一块内存。同时,top命令看到的内存并不准,top,命令统计的是RSS字段,其实对于MMAP来说,更准确的应该是统计PSS字段

微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值