私はMSVC9.0を搭載したWindows7でC++を使用しており、MSVC9.0を搭載したWindowsXPSP3でテストおよび再現することもできました。
0.5MBサイズのオブジェクトを1GB割り当てた場合、それらを削除すると、すべて問題なく動作し、期待どおりに動作します。ただし、0.25MBサイズのオブジェクトを削除するときに1GBを割り当てると、メモリは予約されたままになり(アドレス空間モニターでは黄色)、それ以降は0.25MB未満の割り当てにのみ使用できます。
この単純なコードでは、typedefする構造体を変更することで両方のシナリオをテストできます。構造体を割り当てて削除した後、1GBの1MB charバッファーを割り当てて、charバッファーが構造体がかつて占有していたメモリを使用するかどうかを確認します。
struct HalfMegStruct
{
HalfMegStruct():m_Next(0){}
/* return the number of objects needed to allocate one gig */
static int getIterations(){ return 2048; }
int m_Data[131071];
HalfMegStruct* m_Next;
};
struct QuarterMegStruct
{
QuarterMegStruct():m_Next(0){}
/* return the number of objects needed to allocate one gig */
static int getIterations(){ return 4096; }
int m_Data[65535];
QuarterMegStruct* m_Next;
};
// which struct to use
typedef QuarterMegStruct UseType;
int main()
{
UseType* first = new UseType;
UseType* current = first;
for ( int i = 0; i < UseType::getIterations(); ++i )
current = current->m_Next = new UseType;
while ( first->m_Next )
{
UseType* temp = first->m_Next;
delete first;
first = temp;
}
delete first;
for ( unsigned int i = 0; i < 1024; ++i )
// one meg buffer, i'm aware this is a leak but its for illustrative purposes.
new char[ 1048576 ];
return 0;
}
以下に、アドレス空間モニター内からの私の結果を示します。これら2つの最終結果の唯一の違いは、1GBマーカーまで割り当てられる構造体のサイズであることを強調しておきます。
これは私には非常に深刻な問題のように思えます。多くの人が苦しんでいて、それを知らない可能性もあります。
- それで、これは設計によるものですか、それともこれはバグと見なされるべきですか?
- 小さな削除されたオブジェクトを、より大きな割り当てで実際に無料で使用できるようにすることはできますか?
- そして、好奇心から、MacまたはLinuxマシンも同じ問題に苦しんでいますか?