Javaでオブジェクト/配列を割り当てるときにオーバーヘッドが発生するのはなぜですか?


9

Javaで配列が占めるバイト数は?これは64ビットマシンであり、配列にN個の要素があると仮定します。したがって、これらの要素はすべて、異なるタイプの配列に対して2 * N、4 * N、または8 * Nバイトを占めることになります。

また、Courseraでの講義では、N要素配列では2 * N + 24、4 * N + 24、または8 * N + 24バイトを占有し、24バイトはオーバーヘッドと呼ばれますが、オーバーヘッドがなぜであるかは説明されていません必要。

また、オブジェクトには16バイトのオーバーヘッドがあります。

これらのオーバーヘッドは正確には何ですか?これらの24/16バイトは何で構成されていますか?

また、これらのオーバーヘッドはJavaにのみ存在しますか?C、C ++、Pythonはどうですか?


2
チェックアウト:stackoverflow.com/a/258150/1029272
Deco

1
@Gnijuohz:質問するつもりですか:このオーバーヘッドはどのデータで構成されていますか?
FrustratedWithFormsDesigner 2012

@YannisRizos:OPは、配列について、24バイトに実際に何があるかを知りたいと思います。
FrustratedWithFormsDesigner 2012

@FrustratedWithFormsDesignerああ、それは私の質問よりも質問の解釈が良いようです。
yannis

@YannisRizosは私の悪い態度については申し訳ありません。しかし、あなたがそのリンクを投稿するとき、私は仕方がないのですが、それはある種の皮肉だと思います。防御的すぎると思います。
Gnijuohz 2012

回答:


16

各Javaオブジェクトには、JVMにとって重要な情報を含むヘッダーがあります。最も重要なのは、オブジェクトのクラス(1つのマシンワード)への参照であり、ガベージコレクターによって使用され、別のマシンワード(部分的なワードを使用するとパフォーマンスが悪い)。つまり、これは2ワードです。32ビットシステムでは8バイト、64ビットシステムでは16バイトです。配列には、配列の長さのintフィールドがさらに必要です。これは、別の4バイトであり、64ビットシステムでは8バイトになる可能性があります。

他の言語に関しては:

  • Cにはオブジェクトがないため、もちろんオブジェクトヘッダーはありませんが、個別に割り当てられたメモリの各部分にヘッダーがある場合があります。

  • C ++では、ガベージコレクションがなく、同期に任意のオブジェクトを使用できませんが、オーバーライドされたメソッドを持つクラスがある場合、Javaオブジェクトのクラスへの参照と同様に、各オブジェクトにはvtableへのポインターがあります。ガベージコレクションを行うスマートポインターを使用する場合、ハウスキーピングデータが必要です。

  • Pythonについては知りませんが、クラスへの参照とガベージコレクターのハウスキーピング情報も必要だと思います。


現在、OpenJDKでは、オブジェクトヘッダーのサイズを小さくするための作業が行われています。これは、小さくても重要な手順です。-)
Martijn Verburg 2012

C ++では、ポリモーフィッククラスのみがvtableを必要とします。std::pair<int, float>vtableをまったく必要としない単純なクラスです。その結果、8バイトに収まる可能性があります。また、スマートポインターは実際にはハウスキーピングを追加する必要はありません。明確な反例はですstd::unique_ptr<T>。これは通常、rawと同じ大きさですT*(もちろん、unique_ptrはGCを行いません)。
MSalters 2012

4
Cにもオーバーヘッドがあり、割り当てmallocられたメモリの各ブロックにはfree、使用するヘッダーが必要です。
herby

私が知っている少なくとも1つのmallocライブラリは、32ビットシステムで8バイトのヘッダーを使用します(これは、2バイトの2センチネル値のセット、IIRCで囲まれた4バイトの長さです)。
ドナルフェロー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.