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

发布于 2024-10-14 06:21:10 字数 72 浏览 6 评论 0原文

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

What is the size of an empty class in C++ and Java?
Why is it not zero?
sizeof(); returns 1 in the case of C++.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

等风来 2024-10-21 06:21:10

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

Short Answer for C++:

The C++ standard explicitly says that a class can not have zero size.

Long Answer for C++:

Because each object needs to have a unique address (also defined in the standard) you can't really have zero sized objects.
Imagine an array of zero sized objects. Because they have zero size they would all line up on the same address location. So it is easier to say that objects can not have zero size.

Note:

Even though an object has a non zero size, if it actually takes up zero room it does not need to increase the size of derived class:

Example:

#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
帅冕 2024-10-21 06:21:10

在 Java 的情况下:

  • 没有简单的方法可以找出 Java 中一个对象占用了多少内存;即没有 sizeof 运算符。
  • 有几种方法(例如使用 Instrumentation 或第 3 方库)可以为您提供一个数字,但其含义是微妙的1;请参阅中Java,确定对象大小的最佳方法是什么?
  • 对象的大小(空或非空)是特定于平台的。

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

  • 以便对象可以充当原始锁,
  • 表示其身份哈希码,
  • 指示对象是否已完成,
  • 引用对象的运行时类,
  • 保存对象的 GC 标记位,
  • 以及很快。

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


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

In the Java case:

  • There is no simple way to find out how much memory an object occupies in Java; i.e. there is no sizeof operator.
  • There are a few ways (e.g. using Instrumentation or 3rd party libraries) that will give you a number, but the meaning is nuanced1; see In Java, what is the best way to determine the size of an object?
  • The size of an object (empty or non-empty) is platform specific.

The size of an instance of an "empty class" (i.e. java.lang.Object) is not zero because the instance has implicit state associated with it. For instance, state is needed:

  • so that the object can function as a primitive lock,
  • to represent its identity hashcode,
  • to indicate if the object has been finalized,
  • to refer to the object's runtime class,
  • to hold the object's GC mark bits,
  • and so on.

Current Hotspot JVMs use clever tricks to represent the state in an object header that occupies two 32 bit words. (This expands in some circumstances; e.g. when a primitive lock is actually used, or after identityHashCode() is called.)


1 - For example, does the size of the string object created by new String("hello") include the size of that backing array that holds the characters? From the JVM perspective, that array is a separate object!

°如果伤别离去 2024-10-21 06:21:10

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

Because every C++ object needs to have a separate address, it isn't possible to have a class with zero size (other than some special cases related to base classes). There is more information in C++: What is the size of an object of an empty class? .

箹锭⒈辈孓 2024-10-21 06:21:10

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

Because an object has to have an address in memory, and to have an address in memory, it has to occupy "some" memory. So, it is usually, in C++, the smallest possible amount, i.e. 1 char (but that might depend on the compiler). In Java, I wouldn't be so sure.. it might have some default data (more than just a placeholder like in C++), but it would be surprising if it was much more than in C++.

榕城若虚 2024-10-21 06:21:10

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

我猜想 Java 可能会做几乎相同的事情。 C++ 要求大小至少为 1 的原因是它要求每个对象都是唯一的。例如,考虑一个大小为零的对象数组。所有对象都位于同一地址,因此您实际上只有一个对象。让它为零听起来像是解决问题的良方......

C++ requires that a normal instantiation of it have a size of at least 1 (could be larger, though I don't know of a compiler that does that). It allows, however, an "empty base class optimization", so even though the class has a minimum size of 1, when it's used as a base class it does not have to add anything to the size of the derived class.

I'd guess Java probably does pretty much the same. The reason C++ requires a size of at least 1 is that it requires each object to be unique. Consider, for example, an array of objects with size zero. All the objects would be at the same address, so you'd really only have one object. Allowing it to be zero sounds like a recipe for problems...

我很OK 2024-10-21 06:21:10

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

It's defined by the C++ standard as "a nonzero value", because an allocated object must have a nonzero size in order to have a distinct address. A class that inherits from an empty class, however, is not required to increase in size, barring the usual increase of a vtable if there are virtual functions involved.

冷弦 2024-10-21 06:21:10

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

或者,使用 DataOutputStream 将实例写入文件,关闭文件,然后打开它, file.length() 将为您提供对象的大小。希望这会有所帮助,-MS

I don't know if there is a sizeof() operator in java. What you can do is create an instance of the empty class (have it serializable), send it through a PipedOutputStream and read it as byte array - byteArray.length gives you the size.

Alternatively, write out the instance to a file using DataOutputStream, close the File, open it and file.length() will give you the size of the Object. Hope this helps, - M.S.

拥有 2024-10-21 06:21:10

正如其他人指出的那样,C++ 对象的大小不能为零。仅当类充当不同类的子类时,类的大小才可以为零。看看 @Martin York 的 答案 获取带有示例的描述 - 并且还可以查看并投票其他在这方面正确的答案。

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

As others have pointed out, C++ objects cannot have zero size. Classes can have zero size only when they act as a subclass of a different class. Take a look at @Martin York's answer for a description with examples --and also look and vote the other answers that are correct to this respect.

In Java, in the hotspot VM, there is a memory overhead of 2 machine-words (usually 4 bytes in a 32 arch per word) per object to hold book keeping information together with runtime type information. For arrays a third word is required to hold the size. Other implementations can take a different amount of memory (the classic Java VM, according to the same reference took 3 words per object)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文