gpt4 book ai didi

c++ - 没有碎片化的 STL 容器的大容量内存

转载 作者:可可西里 更新时间:2023-11-01 18:38:53 29 4
gpt4 key购买 nike

目前,当我们想要破坏一个非常大的嵌套列表/复杂对象的映射时,它的内存分配非常零散,我假设 C++ 是调用析构函数并逐个递归地释放内存,这会花费很多时间并且效率低下?

就我而言,我发现销毁一个 300GB 的对象有时需要 1 分钟或更长时间。

操作系统可以有效地终止占用大量内存的进程,因为它只是释放所有内存,而无需过多考虑进程内部的逻辑。

我想知道是否有任何现有的 C/C++ 库可以做到这一点?提供一个自定义的内存分配器来维护一个 id 系统?这样,如果我指定一个 id 来为给定的大型 STL 容器(及其元素)创建分配器。当我想销毁它时,我可以释放分配给指定 id 的所有内存,并丢弃指向外部容器的指针(它会跳过所有析构函数)?就像我们可以“杀死”一个 pid 一样......

谢谢!

最佳答案

这可以通过池分配器和新的放置来完成,当然你会有一些限制,比如在池中为你的插槽找到一个通用的大小(如果你不想要细粒度)但通常情况下很简单场景如下:

struct Foo {
double x, y;
Foo(double x, double y) { this->x = x; this->y = y; };
};

std::byte* buffer = new std::byte[sizeof(Foo) * 10];

Foo* foo1 = new(buffer) Foo(1.0, 2.0);
Foo* foo2 = new(buffer + sizeof(Foo)) Foo(1.0, 2.0);

delete[] buffer;

解释了基本原理。但这必须谨慎完成,因为没有人调用你的析构函数(你应该通过 foo1->~Foo() 手动调用)。但是,如果析构函数没有副作用,或者您可以立即处理它们,那么标准允许您不显式调用它。

现在棘手的部分是,如果您使用的是 STL 集合,那么它们会在内部进行大量分配来存储它们的需求(尤其是像 std::mapstd::list 这样的容器)。所以你需要写一个自定义 allocator<T> 它包装了一个有效的池化方案。

关于c++ - 没有碎片化的 STL 容器的大容量内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54489818/

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