gpt4 book ai didi

c++ - 对 C++ 堆分配器和 STL 进行碎片整理

转载 作者:可可西里 更新时间:2023-11-01 17:56:28 38 4
gpt4 key购买 nike

我希望编写一个自碎片整理内存管理器,其中将一个简单的递增堆分配器与一个简单的压缩碎片整理程序结合使用。

粗略的方案是从最低内存地址开始向上分配 block ,并保持簿记信息从最高内存地址开始向下工作。

内存管理器会传回智能指针 - boost 的 intrusive_ptr 对簿记结构来说似乎是最明显的,然后它们本身会指向实际的内存块,从而提供一定程度的间接性,以便可以轻松地四处移动 block 。

碎片整理程序将从“生成”书签开始压缩堆以加快进程,并且一次只对固定数量的内存进行碎片整理。指向 block 本身的原始指针在下一次碎片整理之前一直有效,因此可以自由传递,直到提高性能为止。

这方面的具体应用是控制台游戏编程,因此在每一帧的开始或结束时,可以相对安全地完成碎片整理过程。

所以我的问题是,是否有人将这种分配方案与 STL 结合使用,它是否会像我怀疑的那样完全破坏 STL。我可以看到 std::list< intrusive_ptr > 在 intrusive_ptr 级别工作,但是 STL 列表节点本身的分配如何覆盖 next/prev 指针使其成为 intrusive_ptr 本身,或者我只需要有一个标准堆分配器以及这个更动态的分配器。

最佳答案

如果您要在内存中移动对象,那么您不能完全通用地执行此操作。您将只能对那些知道它们可能被移动的对象执行此操作。您还需要一个锁定机制。当一个函数正在一个对象上被调用时,它就不能被移动。

原因是整个 C++ 模型依赖于位于内存中固定点的对象,因此如果线程正在调用对象上的方法,则该线程暂停并且对象移动,当线程恢复时会发生灾难。

任何持有指向另一个可能被移动的对象(包括其自身的子对象)的原始内存指针的对象都不会工作。

这样的内存管理方案可能有效,但您必须非常小心。您需要严格执行句柄和句柄-> 指针锁定语义。

对于STL容器,你可以自定义分配器,但它仍然需要返回固定的原始内存指针。您不能返回可能移动的地址。出于这个原因,如果您使用 STL 容器,它们必须是句柄容器,并且节点本身将是普通的动态分配内存。您可能会发现,与使用 STL 相比,您在句柄间接寻址中的开销过多,并且在句柄集合的碎片化方面仍然存在问题。

使用直接理解您的句柄的容器可能是唯一的前进方向,即使那样,与使用固定在内存中的传统对象的 C++ 应用程序相比,仍然可能有很多开销。

关于c++ - 对 C++ 堆分配器和 STL 进行碎片整理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1450896/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com