Dの詳細はわかりませんが、Javaと.netの両方で、すべてのクラスオブジェクトにはそのタイプに関する情報が含まれており、モニターロックのターゲットであるかどうか、ファイナライズクリーンアップの対象であるかどうかなどの情報も保持されています。他のもの。すべてのオブジェクトがそのような情報を格納する標準的な手段を持つことで、言語やフレームワークのユーザーと実装者の両方にとって多くのことがより便利になります。ちなみに、.netの32ビットバージョンでは、オブジェクトの最小サイズが12バイトであることを除いて、各オブジェクトのオーバーヘッドは8バイトです。この最小値は、ガベージコレクターがオブジェクトを移動するときに、
編集
データ項目への参照を永続化できる必要があるためにクラスを使用する場合、スペースは貴重であり、データ項目がいつまだ有用でいつ廃止されるかがわかるような使用パターンです。構造体の配列を定義してから、インデックスを配列要素に渡すことができる場合があります。プログラムの構造により、割り当てられるすべてのアイテムが1回だけリリースされ、リリースされると使用されないようにすることができれば、これを非常に効率的に処理するコードを記述できます。
オブジェクトへの最後の参照がいつスコープ外になるかを簡単に判断できない場合は、8バイトが非常に妥当なレベルのオーバーヘッドになります。ほとんどのフレームワークでは、オブジェクトが32ビット境界に整列されると予想されます(したがって、バイトを追加すると、サイズが12ではなく9にプッシュされることに驚いています)。システムにコモドール64(*)よりも優れたガベージコレクターが搭載される場合、使用されているものと使用されていないものを示すために、オブジェクトごとに最小限のオーバーヘッドが必要になります。さらに、補足情報を含めることができるオブジェクトと含めることができないオブジェクトに別々のヒープを持たせたい場合を除いて、すべてのオブジェクトに補足情報ポインター用のスペースを含めるか、すべての補足情報用のスペースを含めます(ロック、放棄通知要求など)。2つのカテゴリのオブジェクトに別々のヒープを設定することが有益な場合もありますが、その利点が複雑さの追加を正当化することはほとんどありません。
(*)コモドール64ガベージコレクターは、メモリの先頭から下に向かって文字列を割り当てることで機能し、変数(GCされていない)はボトムアップで割り当てられました。メモリがいっぱいになると、システムはすべての変数をスキャンして、最上位のアドレスに格納されている文字列への参照を見つけます。次に、その文字列はメモリの最上部に移動され、その文字列へのすべての参照が更新されます。次に、システムはすべての変数をスキャンして、移動したばかりのアドレスの下の最も高いアドレスにある文字列への参照を見つけ、それに対するすべての参照を更新します。移動する文字列が見つからなくなるまで、このプロセスが繰り返されます。このアルゴリズムでは、文字列とともにメモリに追加のデータを保存する必要はありませんでしたが、もちろん非常に低速でした。コモドール128ガベージコレクターは、GCスペースの各文字列とともに、参照を保持する変数へのポインターと、GCスペースで次に低い文字列を見つけるために使用できる長さバイトを格納します。したがって、各文字列をチェックして、それがまだ使用されているかどうかを確認し、使用されている場合はメモリの先頭に再配置できます。はるかに高速ですが、文字列ごとに3バイトのオーバーヘッドが発生します。