Jus*_* L. 6 macos memory-management
我的程序有一个自定义分配器,它使用mmap(MAP_ANON | MAP_PRIVATE). 当它不再需要内存时,分配器调用munmap或madvise(MADV_FREE)。 MADV_FREE保持映射,但告诉操作系统它可以丢弃与映射关联的物理页面。
调用MADV_FREE您最终将再次需要的页面比调用munmap然后mmap再次调用要快得多。
这对我来说几乎完美。唯一的问题是,在 MacOS 上,MADV_FREE 对于摆脱我要求它释放的页面非常懒惰。事实上,只有当另一个应用程序有内存压力时,它才会摆脱它们。在它清除我释放的页面之前,MacOS 报告我的程序仍在使用该内存;在活动监视器中,它的“真实内存”列不反映释放的内存。
这使我很难衡量我的程序实际使用了多少内存。(测量 RSS 的难度使我们无法在 10.5 上登陆自定义分配器。)
我可以分配一大堆内存来强制操作系统释放这些页面,但除了花费很长时间之外,这可能会产生其他副作用,例如导致我的程序的一部分被分页到磁盘。
在百灵鸟上,我尝试了该purge命令,但没有任何效果。
如何强制 MacOS 清除这些 MADV_FREE 页面?或者,我如何询问 MacOS 我的进程在内存中有多少 MADV_FREE 页面?
这是一个测试程序,如果有帮助的话。程序进入睡眠状态后,活动监视器的“真实内存”列显示为 512MB。在我的 Linux 机器上,top 根据需要显示 256MB 的 RSS。
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
#define SIZE (512 * 1024 * 1024)
// We use MADV_FREE on Mac and MADV_DONTNEED on Linux.
#ifndef MADV_FREE
#define MADV_FREE MADV_DONTNEED
#endif
int main()
{
char *x = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
// Touch each page we mmap'ed so it gets a physical page.
int i;
for (i = 0; i < SIZE; i += 1024) {
x[i] = i;
}
madvise(x, SIZE / 2, MADV_FREE);
fprintf(stderr, "Sleeping. Now check my RSS. Hopefully it's %dMB.\n", SIZE / (2 * 1024 * 1024));
sleep(1024);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1346 次 |
| 最近记录: |