std :: unique_ptr是底层对象的两倍

nad*_*ime 9 c++ unique-ptr

我遇到了问题(特别是MSFT VS 10.0实现)std :: unique_ptrs.当我创建它们的std :: list时,我使用的内存是我创建std :: list的基础对象的两倍(注意:这是一个大对象 - 大约200字节,所以它不仅仅是一个附近的额外参考柜台).

换句话说,如果我跑:

std::list<MyObj> X;
X.resize( 1000, MyObj());
Run Code Online (Sandbox Code Playgroud)

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

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

我已经检查了MSFT实现,我没有看到任何明显的东西 - 任何人遇到这个并有任何想法?

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

  1. 创建一个std::list100000 MyObj
  2. 创建一个std::list100000 MyObj*
  3. 创建一个std::list100000 int*
  4. 创建一个std::list50000 int*

在每种情况下,列表中的每个add'l成员,无论是指针还是其他,都会使我的应用程序膨胀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;
};
Run Code Online (Sandbox Code Playgroud)

Pub*_*bby 3

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

例如,这个:

for(int i = 0; i < 100; ++i) {
  new int;
}
Run Code Online (Sandbox Code Playgroud)

将使用比这更多的内存:

new int[100];
Run Code Online (Sandbox Code Playgroud)

即使分配的金额是相同的。


编辑:

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