gpt4 book ai didi

c++ - std::unique_ptr 是基础对象的两倍大

转载 作者:可可西里 更新时间:2023-11-01 16:38:58 26 4
gpt4 key购买 nike

我遇到了一个问题(特别是 MSFT VS 10.0 的实现)std::unique_ptrs。当我创建它们的 std::list 时,我使用的内存是创建仅底层对象的 std::list 时的两倍(注意:这是一个大对象——~200 字节,所以它不仅仅是一个周围有额外的引用计数器)。

换句话说,如果我运行:

std::list<MyObj> X;
X.resize( 1000, MyObj());

我的应用程序需要的内存是我运行时的一半:

std::list<std::unique_ptr<MyObj>> X;
for ( int i=0; i<1000; i++ ) X.push_back(std::unique_ptr<MyObj>(new MyObj()));

我检查了 MSFT 的实现,但没有发现任何明显的问题——有人遇到过这个问题并有任何想法吗?

编辑: 好的,更清楚/具体一点。这显然是 Windows 内存使用问题,我显然遗漏了一些东西。我现在尝试了以下方法:

  1. 创建一个包含 100000 个 MyObj 的 std::list
  2. 创建一个包含 100000 MyObj* 的 std::list
  3. 创建一个 100000 int* 的 std::list
  4. 创建一个 50000 int* 的 std::list

在每种情况下,列表中的每个附加成员(无论是指针还是其他)都会使我的应用程序膨胀 4400(!) 字节。这是一个 64 位版本的版本,不包含任何调试信息(链接器 > 调试 > 生成调试信息设置为否)。

我显然需要对此进行更多研究,以将其缩小到一个较小的测试用例。

对于那些感兴趣的人,我正在使用 Process Explorer 确定应用程序大小.

原来这完全是堆碎片。多么可笑。每个 8 字节对象 4400 字节!我切换到预分配,问题完全消失了——我已经习惯了依赖按对象分配的低效率,但这太荒谬了。

下面的 MyObj 实现:

class   MyObj
{
public:
MyObj() { memset(this,0,sizeof(MyObj)); }

double m_1;
double m_2;
double m_3;
double m_4;
double m_5;
double m_6;
double m_7;
double m_8;
double m_9;
double m_10;
double m_11;
double m_12;
double m_13;
double m_14;
double m_15;
double m_16;
double m_17;
double m_18;
double m_19;
double m_20;
double m_21;
double m_22;
double m_23;
CUnit* m_UnitPtr;
CUnitPos* m_UnitPosPtr;
};

最佳答案

增加的内存可能来自堆的低效率——由于内部碎片和 malloc 数据,您必须为分配的每个 block 支付额外费用。您正在执行两倍的分配量,这将招致惩罚。

例如,这个:

for(int i = 0; i < 100; ++i) {
new int;
}

将使用比这更多的内存:

new int[100];

即使分配的金额相同。


编辑:

我在 Linux 上使用 GCC 使用 unique_ptr 时使用的内存增加了大约 13%。

关于c++ - std::unique_ptr 是基础对象的两倍大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8299005/

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