C ++,java中空类的大小是多少?

C ++和Java中空类的大小是多少? 为什么不是零? sizeof(); 在C ++的情况下返回1。

简答:

该标准明确指出一个类的大小不能为零。

答案很长:

因为每个对象都需要一个唯一的地址(也在标准中定义),所以你不能真正拥有零大小的对象。
想象一个零大小的对象数组。 因为它们的大小为零,所以它们都排在同一个地址位置。 因此,更容易说对象的大小不能为零。

注意:

即使对象具有非零大小,如果它实际占用零空间,则不需要增加派生类的大小:

例:

 #include  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运算符。
  • 对象的大小(空或非空)是特定于平台的。

“空类”(即java.lang.Object )实例的大小不为零,因为实例具有与之关联的隐式状态。 例如,需要状态:

  • 这样对象就可以作为原始锁,
  • 表示其身份哈希码,
  • 指示对象是否已完成,
  • 引用对象的运行时类,
  • 保持对象的GC标记位,
  • 等等。

当前的Hotspot JVM使用巧妙的技巧来表示占用两个32位字的对象头中的状态。 (这在某些情况下会扩展;例如,当实际使用原始锁时,或者在调用identityHashCode()之后。)

因为每个C ++对象都需要一个单独的地址,所以不可能有一个零大小的类(除了一些与基类相关的特殊情况)。 C ++中有更多信息:空类对象的大小是多少? 。

因为一个对象必须在内存中有一个地址,并且在内存中有一个地址,所以它必须占用“一些”内存。 因此,在C ++中,它通常是可能的最小量,即1个字符(但可能取决于编译器)。 在Java中,我不太确定……它可能有一些默认数据(不仅仅是像C ++中的占位符),但如果它比C ++中的更多,那将是令人惊讶的。

C ++要求它的正常实例化大小至少为1(可能更大,但我不知道编译器会这样做)。 但是,它允许“空基类优化”,因此即使该类的最小大小为1,当它用作基类时,它也不必向派生类的大小添加任何内容。

Java可能几乎一样。 C ++需要大小至少为1的原因是它要求每个对象都是唯一的。 例如,考虑一个大小为零的对象数组。 所有对象都在同一个地址,所以你真的只有一个对象。 允许它为零听起来像是问题的秘诀……

它由C ++标准定义为“非零值”,因为分配的对象必须具有非零大小才能具有不同的地址。 但是,从空类inheritance的类不需要增加大小,除非涉及虚函数,否则通常会增加vtable。

我不知道java中是否有sizeof()运算符。 你可以做的是创建一个空类的实例(让它可序列化),通过PipedOutputStream发送它并将其作为字节数组读取 – byteArray.length给你大小。

或者,使用DataOutputStream将实例写出到文件,关闭File,打开它,file.length()将为您提供Object的大小。 希望这会有所帮助, – MS

正如其他人所指出的,C ++对象的大小不能为零。 只有当类充当不同类的子类时,它们才能具有零大小。 看一下@Martin York的回答以获得带有示例的描述 – 并查看并投票给出这方面正确的其他答案。

在Java中,在热点VM中 ,每个对象存在2个机器字(通常每个字32个字节中4个字节)的存储器开销,以将书籍保存信息与运行时类型信息一起保存。 对于数组,需要第三个字来保持大小。 其他实现可以占用不同的内存量(经典的Java VM,根据相同的引用,每个对象占用3个字)