C ++およびJavaの空のクラスのサイズはどれくらいですか?なぜゼロではないのですか?
sizeof();
C++の場合は1を返します。
8 に答える
C ++の短い答え:
C ++標準では、クラスのサイズをゼロにすることはできないと明示的に規定されています。
C ++の長い答え:
各オブジェクトには一意のアドレス(標準でも定義されている)が必要なため、実際にはサイズがゼロのオブジェクトを作成することはできません。
サイズがゼロのオブジェクトの配列を想像してみてください。サイズがゼロであるため、すべて同じアドレス位置に整列します。したがって、オブジェクトのサイズをゼロにすることはできないと言うのは簡単です。
ノート:
オブジェクトのサイズがゼロ以外であっても、実際にゼロのスペースを占める場合は、派生クラスのサイズを増やす必要はありません。
例:
#include <iostream>
class A {};
class B {};
class C: public A, B {};
int main()
{
std::cout << sizeof(A) << "\n";
std::cout << sizeof(B) << "\n";
std::cout << sizeof(C) << "\n"; // Result is not 3 as intuitively expected.
}
g++ ty.cpp
./a.out
1
1
1
Javaの場合:
- オブジェクトがJavaで占有しているメモリの量を知る簡単な方法はありません。つまり、
sizeof
演算子はありません。 Instrumentation
番号を与える方法はいくつかありますが(たとえば、サードパーティのライブラリを使用するなど)、意味は微妙です1。Javaでは、オブジェクトのサイズを決定するための最良の方法は何ですか?を参照してください。- オブジェクトのサイズ(空または空でない)は、プラットフォームによって異なります。
「空のクラス」(つまりjava.lang.Object
)のインスタンスのサイズは、インスタンスに暗黙の状態が関連付けられているため、ゼロではありません。たとえば、状態が必要です。
- オブジェクトがプリミティブロックとして機能できるように、
- IDハッシュコードを表すために、
- オブジェクトが完成したかどうかを示すために、
- オブジェクトのランタイムクラスを参照するには、
- オブジェクトのGCマークビットを保持するには、
- 等々。
現在のホットスポットJVMは、巧妙なトリックを使用して、2つの32ビットワードを占めるオブジェクトヘッダーの状態を表します。(これは、状況によっては拡張されます。たとえば、プリミティブロックが実際に使用される場合、または後でidentityHashCode()
呼び出される場合などです。)
1-たとえば、によって作成された文字列オブジェクトのサイズには、文字new String("hello")
を保持するバッキング配列のサイズが含まれていますか?JVMの観点からは、その配列は別のオブジェクトです。
すべてのC++オブジェクトは個別のアドレスを持つ必要があるため、サイズがゼロのクラスを持つことはできません(基本クラスに関連するいくつかの特別な場合を除く)。C ++にはさらに多くの情報があります:空のクラスのオブジェクトのサイズはどれくらいですか?。
オブジェクトはメモリ内にアドレスを持っている必要があり、メモリ内にアドレスを持っている必要があるため、「いくらかの」メモリを占有する必要があります。したがって、通常、C ++では、可能な最小量、つまり1文字です(ただし、コンパイラによって異なる場合があります)。Javaでは、私にはよくわかりません。デフォルトのデータ(C ++のような単なるプレースホルダー以上のもの)があるかもしれませんが、C++よりもはるかに多い場合は驚くべきことです。
C ++では、通常のインスタンス化のサイズが少なくとも1である必要があります(これを行うコンパイラーはわかりませんが、それより大きくなる可能性があります)。ただし、これにより「空の基本クラスの最適化」が可能になるため、クラスの最小サイズが1であっても、基本クラスとして使用する場合は、派生クラスのサイズに何も追加する必要はありません。
Javaはおそらくほとんど同じことをしていると思います。C ++が少なくとも1のサイズを必要とする理由は、各オブジェクトが一意である必要があるためです。たとえば、サイズがゼロのオブジェクトの配列について考えてみます。すべてのオブジェクトは同じアドレスにあるため、実際には1つのオブジェクトしかありません。ゼロにすることは、問題のレシピのように聞こえます...
割り当てられたオブジェクトは、個別のアドレスを持つためにゼロ以外のサイズである必要があるため、C++標準では「ゼロ以外の値」として定義されています。ただし、空のクラスから継承するクラスは、サイズを大きくする必要はありません。仮想関数が関係している場合は、通常のvtableの増加は除きます。
javaにsizeof()演算子があるかどうかはわかりません。空のクラスのインスタンスを作成し(シリアル化可能にします)、PipedOutputStreamを介して送信し、バイト配列として読み取ります。byteArray.lengthでサイズがわかります。
または、DataOutputStreamを使用してインスタンスをファイルに書き出し、ファイルを閉じて開きます。file.length()を使用すると、オブジェクトのサイズがわかります。これがお役に立てば幸いです-MS
他の人が指摘しているように、C++オブジェクトのサイズをゼロにすることはできません。クラスは、別のクラスのサブクラスとして機能する場合にのみ、サイズをゼロにすることができます。例を含む説明については、 @ Martin Yorkの回答を参照してください。また、この点に関して正しい他の回答を確認して投票してください。
Javaでは、ホットスポットVMで、オブジェクトごとに2マシンワード(通常、ワードあたり32アーチで4バイト)のメモリオーバーヘッドがあり、実行時型情報と一緒に簿記情報を保持します。配列の場合、サイズを保持するために3番目のワードが必要です。他の実装では、異なる量のメモリを使用する可能性があります(同じ参照によると、従来のJava VMはオブジェクトごとに3ワードを使用していました)