2016-09-03 5 views
4

なぜオブジェクトヘッダーが64ビットアプリケーションで2倍大きくなったのか分かりません。 オブジェクトヘッダーは8バイトで、64ビットでは16バイトです。これらの追加バイトは何のために使用されますか?64ビットアーキテクチャでオブジェクトヘッダーサイズが倍増したのはなぜですか?

+0

https://codeblog.jonskeet.uk/2011/04/05/of-memory-and-strings/ –

+1

[.NETオブジェクトのメモリオーバーヘッドとは何か](http: //stackoverflow.com/questions/10655829/what-is-the-memory-overhead-of-a-net-object) –

答えて

8

オブジェクトヘッダーは、syncblkとメソッドテーブルポインタ(別名「タイプハンドル」)の2つのフィールドで構成されています。 2番目のフィールドはわかりやすいので、それはポインタですは、は64ビットモードで4から8バイトに増加する必要があります。

syncblkのほうがはるかに明白ではなく、フラグと値(ロック所有者スレッドID、ハッシュコード、同期ブロックインデックス)が混在しています。 64ビットモードでそれを大きくする理由はありません。重要なことは、の後にの後にオブジェクトがGCによって収集されることです。ヒープを圧縮することによって空きスペースがなくならなかった場合、オブジェクト・スペースはフリー・ブロック・リストに参加します。二重リンクリストのように機能します。第2のフィールドは、次の空きブロックへの順方向ポインタである。オブジェクトデータスペースは空きブロックのサイズを格納するために使用され、オブジェクトが決して12バイト未満でない基本的な理由があります。また、syncblkは、前の空きブロックにバックポインタを格納します。今はポインタを格納するのに十分な大きさでなければならず、したがって8バイトに成長する必要があります。したがって、8 + 8 = 16バイトです。

Fwiwでは、64ビットモードの最小オブジェクトサイズは24バイトですが、8 + 8 + 4 = 20バイトはすべてうまくいくはずですが、すべてが8に揃っていることを保証します。 L1キャッシュ・ラインにまたがってポインタ値を持つことは決して望ましくありません。約3倍速くアクセスします。 <gcAllowVeryLargeObjects>オプションは後で追加される別の理由です。

+0

ありがとう、答えは非常に説明的です。 –

関連する問題