使用 gcc/linux 进行就地重新分配

发布于 2024-08-02 13:04:10 字数 227 浏览 1 评论 0原文

有这样的事吗?我的意思是一些函数,如果可能的话,会重新分配内存而不移动它,或者如果不可能的话,什么也不做。在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

定格我的天空 2024-08-09 13:04:10

除了使用 mmapmunmap 来消除不需要的多余内容(或 mremap,它可以做同样的事情,但不是标准的) ),没有办法减少分配的内存块的大小。 mmap 具有页面粒度(通常为 4k),因此除非您处理非常大的对象,否则使用它会比只保留过大的对象而不缩小它们更糟糕。

话虽如此,就地收缩内存可能不是一个好主意,因为释放的内存将严重碎片化。一个好的realloc实现会在显着缩小块时移动块,以此作为对内存进行碎片整理的机会。

我猜你的情况是,你有一个分配的内存块,其中有许多其他结构保存着指针,并且你不想使这些指针无效。如果是这种情况,这里有一个可能的通用解决方案:

  1. 将可调整大小的对象分成两个分配,一个固定大小的“头”对象指向第二个可变大小的对象。
  2. 对于需要指向可变大小对象的其他对象,存储一个指向头对象指针和一个整数偏移size_tptrdiff_t) 到可变大小对象中。

现在,即使可变大小对象移动到新地址,对它的引用也不会失效。

如果您从多个线程使用这些对象,则应该在头对象中放置一个读写锁,每当需要访问可变大小对象时对其进行读锁定,并在每次调整可变大小对象时对其进行写锁定目的。

Aside from using mmap and munmap to eliminate the excess you don't need (or mremap, which could do the same but is non-standard), there is no way to reduce the size of an allocated block of memory. And mmap 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:

  1. Break your resizable object up into two allocations, a "head" object of fixed size which points to the second variable-sized object.
  2. For other objects which need to point into the variable-size object, store a pointer to the head object and an integer offset (size_t or ptrdiff_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.

终难遇 2024-08-09 13:04:10

另一个论坛上也提出了类似的问题。我看到的更合理的答案之一涉及使用 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 the MAP_ANONYMOUS flag) and calling mremap without the MREMAP_MAYMOVE flag. A limitation of this approach, though, is that the allocation sizes must be exact multiples to the system's page size.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文