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

时间:2011-01-25 04:14:39

标签: java c++ empty-class

C ++和Java中空类的大小是多少? 为什么不是零? 对于C ++,sizeof();返回1。

8 个答案:

答案 0 :(得分:26)

简答:

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

长答案:

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

注意:

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

示例:

#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

答案 1 :(得分:14)

在Java案例中:

  • 没有简单的方法来查明对象在Java中占用多少内存;即没有sizeof运营商。
  • 有几种方法(例如使用Instrumentation或第三方库)会给你一个数字,但意思是细微差别 1 ;见In Java, what is the best way to determine the size of an object?
  • 对象的大小(空或非空)是特定于平台的。

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

  • 以便对象可以作为基元锁,
  • 表示其身份哈希码,
  • 表示对象是否已完成,
  • 引用对象的运行时类
  • 保存对象的GC标记位,
  • 等等。

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


1 - 例如,new String("hello")创建的字符串对象的大小是否包含保存字符的后备数组的大小?从JVM的角度来看,该数组是一个单独的对象!

答案 2 :(得分:4)

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

答案 3 :(得分:4)

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

答案 4 :(得分:3)

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

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

答案 5 :(得分:2)

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

正如其他人所指出的,C ++对象的大小不能为零。只有当类充当不同类的子类时,它们才能具有零大小。请查看@Martin York的answer以获取有关示例的说明 - 并查看并投票选出其他正确的答案。

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