简体   繁体   English

限制malloc()的虚拟内存空间

[英]Limit Virtual Memory space for malloc()

I have written my own my_malloc() function that manages its own physical memory. 我已经编写了自己的my_malloc()函数来管理自己的物理内存。 In my application I want to be able use both the libc malloc() as well as my own my_malloc() function. 在我的应用程序中,我希望能够同时使用libc malloc()和我自己的my_malloc()函数。 So I somehow need to partition the virtual address space, malloc should always assign a virtual address only if its from its dedicated pool, same thing with my_malloc(). 因此,我需要以某种方式划分虚拟地址空间,仅当malloc来自其专用池时才应分配虚拟地址,这与my_malloc()相同。 I cannot limit heap size, I just need to guarantee that malloc() and my_malloc() never return the same/overlapping virtual addresses. 我不能限制堆大小,我只需要保证malloc()和my_malloc()永远不会返回相同/重叠的虚拟地址。

thanks! 谢谢!

One answer is to make your my_malloc use memory allocated by malloc . 一种答案是使my_malloc使用malloc分配的malloc Using big enough blocks would mostly acheive that; 使用足够大的块通常可以达到目标; then within each block your version will maintain its own structures and allocate parts of it to callers. 然后在每个块中,您的版本将维护其自己的结构,并将其部分分配给调用方。

It gets tricky because you can't rely on extending the entire available space for your version, as you can when you get memory from sbrk or similar. 之所以变得棘手,是因为您不能依赖于扩展版本的整个可用空间,就像从sbrk或类似的内存中获取内存一样。 So your version would have to maintain several blocks. 因此,您的版本必须维护几个块。

One possibility would be to have my_malloc() call malloc() at startup to pre-allocate a large pool of memory, then apportion that memory to its callers and manage it accordingly. 一种可能是在启动时让my_malloc()调用malloc()来预分配大内存池,然后将该内存分配给其调用方并相应地进行管理。 However, a full implementation would need to handle garbage collection and defragmentation. 但是,完整的实现将需要处理垃圾回收和碎片整理。

Another possibility would be to have my_malloc() call malloc() each time it needs to allocate memory and simply handle whatever "bookkeeping" aspects you're interested in, such as number of blocks allocated, number of blocks freed, largest outstanding block, total allocated memory, etc . 另一种可能性是, my_malloc()每次需要分配内存时都调用malloc()并简单地处理您感兴趣的任何“簿记”方面,例如分配的块数,释放的块数,最大的未完成块,已分配的总内存 This is by far the safer and more efficient mechanism, as you're passing all of the "hard" operations to malloc() . 到目前为止,这是一种更安全,更有效的机制,因为您将所有“硬”操作都传递给了malloc()

Reserve a large block of virtual address space, and have that be the pool from which my_malloc() allocates. 保留一大块虚拟地址空间,并将其作为my_malloc()分配的池。 Once you have reserved a large contiguous region of memory from the OS, then subsequent calls to malloc() have to come from elsewhere. 一旦从OS保留了大量连续的内存区域,则随后对malloc()调用必须来自其他位置。

For example, on Windows , you can use VirtualAlloc() to reserve a 256mb block of space. 例如, 在Windows上 ,您可以使用VirtualAlloc()保留256mb的空间。 The memory won't actually be allocated until you "commit" it with a subsequent call, but it will reserve an address range (such as 0x4000000-0x5000000) which subsequent malloc() will not use. 直到您通过后续调用“提交”内存才真正分配内存,但是它将保留一个地址范围(例如0x4000000-0x5000000),后续的malloc()将不使用该地址范围。 Then your my_malloc() can commit blocks out of this reserved range as requested, and subdivide them by whatever allocation scheme you've written. 然后,您的my_malloc()可以根据请求提交超出此保留范围的块,并通过您编写的任何分配方案对其进行细分。

I'm told the equivalent Linux call is mmap() . 我被告知等效的Linux调用是mmap() ( edit: I previously said "kmalloc or vmalloc , depending on whether you need the memory to be physically contiguous or not," but those are kernel-level functions.) 编辑:我之前说过“ kmalloc或vmalloc ,取决于您是否需要内存在物理上是连续的”,但这是内核级的函数。)

We use this mechanism in our app to redirect all allocations of a certain size into our own custom pooled-block allocator for speed and efficiency. 我们在应用程序中使用此机制将一定大小的所有分配重定向到我们自己的自定义池块分配器中,以提高速度和效率。 Among other things, it lets us reserve virtual pages in certain specific sizes that are more efficient for the CPU to handle . 除其他事项外,它还使我们可以保留某些特定大小的虚拟页面, 这些大小 对于CPU而言更为有效

If you add an mmap(2) call near the start of the program, you can allocate as much memory as you need with whatever addresses you need (see the hint , that's usually left NULL for the OS to determine) immediately; 如果在程序开始附近添加mmap(2)调用,则可以立即根据需要分配任意数量的内存,以及所需的任何地址(请参见提示 ,通常由OS决定是否为NULL ); that will prevent malloc(3) , or any other memory allocation routines, from getting those particular pages. 这将阻止malloc(3)或任何其他内存分配例程获取那些特定页面。

Don't worry about the memory usage; 不用担心内存使用情况; since modern systems are quite happy to overcommit, you'll only use a few hundred kilobytes more kernel space to handle page tables. 由于现代系统非常乐于过度使用,因此您只需要使用几百千字节的内核空间来处理页表。 Not too bad. 还不错

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM