C++ 在 OS X 中移植 VirtualFree
C++ porting VirtualFree in OS X
我正在尝试为我们的内存管理做一个端口,其中一些分配器使用虚拟内存机制来保留地址 space 而无需(在开始时)分配任何物理内存,然后仅在它们分配内存时才分配内存需要。
该代码基于 Windows' VirtualAlloc 和 VirtualFree 来实现,现在我正在尝试将此代码移植到 Apple OS X,据我所知,没有这样的API,过了一会儿我想出了下面的代码:
//to reserve virtual address space
//equivalent of VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS)
void* ptr = mmap(NULL, size, PROT_NONE, (MAP_PRIVATE | MAP_ANON), -1, 0);
msync(ptr, size, (MS_SYNC | MS_INVALIDATE));
//to free ALL virtual address space
//equivalent of VirtualFree(addr, 0, MEM_RELEASE)
//where "size" is the size of the entire virtual address space and "addr" the starting address
msync(addr, size, MS_SYNC);
munmap(addr, size);
//to allocate physical memory
//equivalent of VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE)
void* ptr = mmap(addr, size, (PROT_READ | PROT_WRITE), (MAP_FIXED | MAP_SHARED | MAP_ANON), -1, 0);
msync(addr, size, (MS_SYNC | MS_INVALIDATE));
我唯一想不通的是如何将 VirtualFree 的使用移植到 free/uncommit 物理内存的一部分,模仿 VirtualFree 调用:
VirtualFree(addr, size, MEM_DECOMMIT);
我已尝试使用所需的地址和大小调用 munmap,但它不会释放内存...而调用它以释放所有虚拟 space 效果很好。
有人可以帮我完成这个任务吗?
感谢这个博客,我找到了自己问题的答案:
http://blog.nervus.org/managing-virtual-address-spaces-with-mmap/
我也 post 在这里他的解决方案以防 link 死亡:
void DecommitMemory(void* addr, size_t size)
{
// instead of unmapping the address, we're just gonna trick
// the TLB to mark this as a new mapped area which, due to
// demand paging, will not be committed until used.
mmap(addr, size, PROT_NONE, MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0);
msync(addr, size, MS_SYNC|MS_INVALIDATE);
}
我正在尝试为我们的内存管理做一个端口,其中一些分配器使用虚拟内存机制来保留地址 space 而无需(在开始时)分配任何物理内存,然后仅在它们分配内存时才分配内存需要。
该代码基于 Windows' VirtualAlloc 和 VirtualFree 来实现,现在我正在尝试将此代码移植到 Apple OS X,据我所知,没有这样的API,过了一会儿我想出了下面的代码:
//to reserve virtual address space
//equivalent of VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS)
void* ptr = mmap(NULL, size, PROT_NONE, (MAP_PRIVATE | MAP_ANON), -1, 0);
msync(ptr, size, (MS_SYNC | MS_INVALIDATE));
//to free ALL virtual address space
//equivalent of VirtualFree(addr, 0, MEM_RELEASE)
//where "size" is the size of the entire virtual address space and "addr" the starting address
msync(addr, size, MS_SYNC);
munmap(addr, size);
//to allocate physical memory
//equivalent of VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE)
void* ptr = mmap(addr, size, (PROT_READ | PROT_WRITE), (MAP_FIXED | MAP_SHARED | MAP_ANON), -1, 0);
msync(addr, size, (MS_SYNC | MS_INVALIDATE));
我唯一想不通的是如何将 VirtualFree 的使用移植到 free/uncommit 物理内存的一部分,模仿 VirtualFree 调用:
VirtualFree(addr, size, MEM_DECOMMIT);
我已尝试使用所需的地址和大小调用 munmap,但它不会释放内存...而调用它以释放所有虚拟 space 效果很好。
有人可以帮我完成这个任务吗?
感谢这个博客,我找到了自己问题的答案: http://blog.nervus.org/managing-virtual-address-spaces-with-mmap/
我也 post 在这里他的解决方案以防 link 死亡:
void DecommitMemory(void* addr, size_t size)
{
// instead of unmapping the address, we're just gonna trick
// the TLB to mark this as a new mapped area which, due to
// demand paging, will not be committed until used.
mmap(addr, size, PROT_NONE, MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0);
msync(addr, size, MS_SYNC|MS_INVALIDATE);
}