Let's write a test program:
public static void main(String[] args) throws Exception { RandomAccessFile randomAccessFile = new RandomAccessFile("./FileMmapTest.txt", "rw"); FileChannel channel = randomAccessFile.getChannel(); MappedByteBuffer []mappedByteBuffers = new MappedByteBuffer[5]; //Open MappedByteBuffer with five identical files, but the actual machine memory is only 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); } }
When the program runs to the last dead loop, let's look at the result of 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
You can observe a very interesting phenomenon. This process occupies 124% of the memory. In fact, Swap is 0. The total occupation is less than 100%. Why?
Let's take a look at the smaps file of this process. The process number here is 25485, and our mapped file is 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
The meanings of the eight important fields are as follows:
- Size: indicates the size of the mapped area in the virtual memory space.
- Rss: indicates how much space the mapped area currently occupies in physical memory
- Pss: the amount of physical memory used by the virtual memory area after calculation (some memory will be shared with other processes, such as mmap). For example, the physical memory mapped by this region is also mapped by another process, and the size of this part of physical memory is 1000KB, then the process allocates half of the memory, that is, Pss=500KB.
- Shared_Clean: the size of the non rewritten page shared with other processes
- Shared_Dirty: the size of the rewritten page shared with other processes
- Private_Clean: the size of the private page that has not been overwritten.
- Private_Dirty: the size of the private page that has been overwritten.
- Swap: indicates the size of non mmap memory (also known as anonymous memory, such as the memory dynamically allocated by malloc) that is swapped to the swap space due to insufficient physical memory.
We can see that adding up the Pss of the five mappedbytebuffers is exactly 2097151, which is the size of our mapping. It can be inferred that the implementation of our five mappedbytebuffers in linux corresponds to the same block of memory.
At the same time, the memory seen by the top command is not accurate. The top command counts RSS fields. In fact, for MMAP, it is more accurate to count PSS fields
WeChat search "my programming meow" attention to the official account, daily brush, easy to upgrade technology, and capture all kinds of offer: