У меня проблема с (в частности, с реализацией 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, и я, очевидно, что-то упускаю.Теперь я попробовал следующее:
- Создать
std::list
из 100000 MyObj - Создать
std::list
из 100000 MyObj * - Создать
std::list
из 100000 int * - Создайте
std::list
из 50000 int *
В каждом случае каждый добавочный член списка, будь то указатель или нет, раздувает мойприменение 4400 (!) байтов .Это в 64-разрядной версии, без любой отладочной информации, включенной (Linker> Debugging> Generate Debug Info, установленной в No).
Мне, очевидно, нужно немного больше изучить это, чтобы сузить его до небольшого контрольного примера.
Для тех, кто заинтересован, я определяю размер приложения с помощью Process Explorer .
Оказывается, это была целая фрагментация кучи.Как смешно.4400 байт на 8-байтовый объект!Я переключился на предварительное распределение, и проблема полностью ушла - я привык к некоторой неэффективности, полагаясь на распределение для каждого объекта, но это было просто смешно.
Реализация 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;
};