自作GC作るぞー
という事でちょろっと書いたプログラムでメモリの使われ方を検証メモ
使用クラスの解説
- GCはガベージコレクション(になる予定 現在は適当なサイズのメモリを確保してそこからGC_OBJにメモリを割り当てるだけ)
- GC_OBJはint[12]を持ちnew,deleteをオーバーライド 確保したメモリサイズを出力
- GC_OBJ_EXはGC_OBJを継承し、int[12]を持つ
- GC_OBJ_EX2はGC_OBJ_EXを継承し、int[12]を持つ
GC_OBJのデストラクタはvirtualを付ける つけない場合継承したクラスのdelete時に渡されるsizeが基底クラスのサイズで渡されるためうまく解放されない(ガベージコレクションによるメモリ開放処理だと継承先がポインタで何か指していた場合メモリリークが起きる?(未検証))
以下コード
//メモリ確保 メモリ開放をするテストアプリ 確保したメモリサイズを表示
//本来メモリ開放部分はガベージコレクションが行うようにするがテスト段階なので
int main() {
srand(time(NULL));
//ガベージコレクション用メモリ確保
GC::GetInstance()->SetMemorySize(1024 * 1024 * 8);
//ガベージコレクションからメモリを確保
GC_OBJ* hoge = new GC_OBJ();
GC_OBJ* piyo = new GC_OBJ_EX();
GC_OBJ* foo = new GC_OBJ_EX2();
//ガベージコレクションからメモリを確保
GC_OBJ* hogeArr = new GC_OBJ[2]();
GC_OBJ* piyoArr = new GC_OBJ_EX[2]();
GC_OBJ* fooArr = new GC_OBJ_EX2[2]();
//メモリ開放 この処理は本来ガベージコレクションにやらせるが未実装のため
delete hoge;
delete piyo;
delete foo;
//メモリ開放 この処理は本来ガベージコレクションにやらせるが未実装のため
delete[] hogeArr;
delete[] piyoArr;
delete[] fooArr;
return 0;
}
出力結果
GC_OBJ52byte確保
GC_OBJ100byte確保
GC_OBJ148byte確保
GC_OBJ108byte確保
GC_OBJ204byte確保
GC_OBJ300byte確保
GC_OBJ52byte開放
GC_OBJ100byte開放
GC_OBJ148byte開放
GC_OBJ108byte開放
GC_OBJ204byte開放
GC_OBJ300byte開放
GC_OBJのデストラクタにvirtualがない場合
GC_OBJ48byte確保
GC_OBJ96byte確保
GC_OBJ144byte確保
GC_OBJ100byte確保
GC_OBJ196byte確保
GC_OBJ292byte確保
GC_OBJ48byte開放
GC_OBJ48byte開放
GC_OBJ48byte開放
GC_OBJ100byte開放
GC_OBJ100byte開放
GC_OBJ100byte開放
結果からの考察
デストラクタをvirtualにすることで現在どのクラスであるかを記憶する領域が4byte
配列情報を記憶する領域が4byte確保されてるっぽい
GC_OBJのデストラクタにvirtualがない場合開放時すべてGC_OBJであると解釈される
以上車輪の再発明のためのメモでした
参考
これだけ読めば全部がわかるC++のoperator new/deleteオーバーロードの注意点
http://cflat-inc.hatenablog.com/entry/2014/01/28/214820
GCアルゴリズム詳細解説
http://seesaawiki.jp/w/author_nari/