使用 gcc/linux 进行就地重新分配
有这样的事吗?我的意思是一些函数,如果可能的话,会重新分配内存而不移动它,或者如果不可能的话,什么也不做。在 Visual C 中,有 _expand 可以满足我的需求。有谁知道其他平台的等效项,特别是 gcc/linux?我最感兴趣的是尽可能缩小内存(并且标准重新分配可能会移动内存,即使其大小减小,以防有人问)。
我知道没有标准方法可以做到这一点,并且我明确要求依赖于实现的肮脏黑客技巧。列出任何你知道在某处有效的东西。
Is there such a thing? I mean some function that would reallocate memory without moving it if possible or do nothing if not possible. In Visual C there is _expand which does what I want. Does anybody know about equivalents for other platforms, gcc/linux in particular? I'm mostly interested in shrinking memory in-place when possible (and standard realloc may move memory even when its size decreases, in case somebody asks).
I know there is no standard way to do this, and I'm explicitly asking for implementation-dependent dirty hackish tricks. List anything you know that works somewhere.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
除了使用
mmap
和munmap
来消除不需要的多余内容(或mremap
,它可以做同样的事情,但不是标准的) ),没有办法减少分配的内存块的大小。mmap
具有页面粒度(通常为 4k),因此除非您处理非常大的对象,否则使用它会比只保留过大的对象而不缩小它们更糟糕。话虽如此,就地收缩内存可能不是一个好主意,因为释放的内存将严重碎片化。一个好的realloc实现会在显着缩小块时移动块,以此作为对内存进行碎片整理的机会。
我猜你的情况是,你有一个分配的内存块,其中有许多其他结构保存着指针,并且你不想使这些指针无效。如果是这种情况,这里有一个可能的通用解决方案:
size_t
或ptrdiff_t
) 到可变大小对象中。现在,即使可变大小对象移动到新地址,对它的引用也不会失效。
如果您从多个线程使用这些对象,则应该在头对象中放置一个读写锁,每当需要访问可变大小对象时对其进行读锁定,并在每次调整可变大小对象时对其进行写锁定目的。
Aside from using
mmap
andmunmap
to eliminate the excess you don't need (ormremap
, which could do the same but is non-standard), there is no way to reduce the size of an allocated block of memory. Andmmap
has page granularity (normally 4k) so unless you're dealing with very large objects, using it would be worse than just leaving the over-sized objects and not shrinking them at all.With that said, shrinking memory in-place is probably not a good idea, since the freed memory will be badly fragmented. A good
realloc
implementation will want to move blocks when significantly shrinking them as an opportunity to defragment memory.I would guess your situation is that you have an allocated block of memory with lots of other structures holding pointers into it, and you don't want to invalidate those pointers. If this is the case, here is a possible general solution:
size_t
orptrdiff_t
) into the variable-size object.Now, even if the variable-size object moves to a new address, none of the references to it are invalidated.
If you're using these objects from multiple threads, you should put a read-write lock in the head object, read-locking it whenever you need to access the variable-sized object, and write-locking it whenever resizing the variable-sized object.
另一个论坛上也提出了类似的问题。我看到的更合理的答案之一涉及使用
mmap
进行初始分配(使用MAP_ANONYMOUS
标志)并调用mremap
不使用< /em>MREMAP_MAYMOVE
标志。然而,这种方法的一个限制是分配大小必须是系统页面大小的精确倍数。A similar question was asked on another forum. One of the more reasonable answers I saw involved using
mmap
for the initial allocation (using theMAP_ANONYMOUS
flag) and callingmremap
without theMREMAP_MAYMOVE
flag. A limitation of this approach, though, is that the allocation sizes must be exact multiples to the system's page size.