$ sudo dtruss -a ./awesomeProject
...
4374/0x206a2: 15620 6 3 mprotect(0x1BC4000, 0x1000, 0x0) = 0 0
...
4374/0x206a2: 15781 9 4 sysctl([CTL_HW, 3, 0, 0, 0, 0] (2), 0x7FFEEFBFFA64, 0x7FFEEFBFFA68, 0x0, 0x0) = 0 0
4374/0x206a2: 15783 3 1 sysctl([CTL_HW, 7, 0, 0, 0, 0] (2), 0x7FFEEFBFFA64, 0x7FFEEFBFFA68, 0x0, 0x0) = 0 0
4374/0x206a2: 15899 7 2 mmap(0x0, 0x40000, 0x3, 0x1002, 0xFFFFFFFFFFFFFFFF, 0x0) = 0x4000000 0
4374/0x206a2: 15930 3 1 mmap(0xC000000000, 0x4000000, 0x0, 0x1002, 0xFFFFFFFFFFFFFFFF, 0x0) = 0xC000000000 0
4374/0x206a2: 15934 4 2 mmap(0xC000000000, 0x4000000, 0x3, 0x1012, 0xFFFFFFFFFFFFFFFF, 0x0) = 0xC000000000 0
4374/0x206a2: 15936 2 0 mmap(0x0, 0x2000000, 0x3, 0x1002, 0xFFFFFFFFFFFFFFFF, 0x0) = 0x59B7000 0
4374/0x206a2: 15942 2 0 mmap(0x0, 0x210800, 0x3, 0x1002, 0xFFFFFFFFFFFFFFFF, 0x0) = 0x4040000 0
4374/0x206a2: 15947 2 0 mmap(0x0, 0x10000, 0x3, 0x1002, 0xFFFFFFFFFFFFFFFF, 0x0) = 0x1BD0000 0
4374/0x206a2: 15993 3 0 madvise(0xC000000000, 0x2000, 0x8) = 0 0
4374/0x206a2:
16004 2 0 mmap(0x0, 0x10000, 0x3, 0x1002, 0xFFFFFFFFFFFFFFFF, 0x0) = 0x1BE0000 0
...
在这小节中,我们通过 macOS 的
dtruss
命令监听并查看了运行这个程序所进行的所有系统调用,发现了与内存管理有一定关系的方法如下:
mmap:创建一个新的虚拟内存区域,但这里需要注意,
就是当系统调用 mmap 时,它只是从虚拟内存中申请了一段空间出来,并不会去分配和映射真实的物理内存,而当你访问这段空间的时候,才会在当前时间真正的去分配物理内存
。那么对应到我们实际应用的进程中,那就是 VSZ 的增长后,而该内存空间又未正式使用的话,物理内存是不会有增长的。
madvise:提供有关使用内存的建议,例如:MADV_NORMAL、MADV_RANDOM、MADV_SEQUENTIAL、MADV_WILLNEED、MADV_DONTNEED 等等。
mprotect:设置内存区域的保护情况,例如:PROT_NONE、PROT_READ、PROT_WRITE、PROT_EXEC、PROT_SEM、PROT_SAO、PROT_GROWSUP、PROT_GROWSDOWN 等等。
sysctl:在内核运行时动态地修改内核的运行参数。
在此比较可疑的是
mmap
方法,它在
dtruss
的最终统计中一共调用了 10 余次,我们可以相信它在 Go Runtime 的时候进行了大量的虚拟内存申请,我们再接着往下看,看看到底是在什么阶段进行了虚拟内存空间的申请。
注:若是 Linux 系统,可使用
strace
命令。