枚举类型需要多少内存?

56

例如,如果我有一个包含两个枚举的Enum,它是否比布尔类型占用更多内存?编程语言:Java、C++

12个回答

54
在Java中,enum是一个完整的类

Java编程语言中的枚举类型比其他语言中的枚举类型更加强大。枚举声明定义了一个类(称为枚举类型)。枚举类体可以包括方法和其他字段。

为了查看每个enum的实际大小,让我们创建一个实际的enum并检查它创建的class文件的内容。
假设我们有以下Constants枚举类:
public enum Constants {
  ONE,
  TWO,
  THREE;
}

编译上述enum并使用javap反汇编生成的class文件,结果如下:
Compiled from "Constants.java"
public final class Constants extends java.lang.Enum{
    public static final Constants ONE;
    public static final Constants TWO;
    public static final Constants THREE;
    public static Constants[] values();
    public static Constants valueOf(java.lang.String);
    static {};
}

该反汇编显示,每个enum字段都是Constantsenum类的实例。(使用javap进行进一步分析将揭示每个字段是通过在静态初始化块中调用new Constants(String)构造函数来创建新对象来初始化的。)
因此,我们可以得知,我们创建的每个enum字段至少会产生JVM中创建对象的开销。

16
在32位平台上,它的大小与int完全相同-它只是指向枚举实例的(32位)指针。每个枚举值在内存中只存在一个实例。 - thenickdude
4
“比纯整数多一点重”的意思是什么?这句话的含义是什么,并且你从文本中获得了什么信息?这句话的出处不清楚,需要更多上下文才能确定其含义。 - Erick Robertson

17
在Java中,每个枚举值应只有一个实例存储在内存中。对该枚举值的引用仅需要该引用的存储。检查枚举值与任何其他引用比较一样高效。

8

7

bool可能被实现为一个字节,但通常在结构体中它会被其他具有对齐要求的元素所包围,这意味着布尔值实际上至少占用与int相同的空间。

现代处理器将数据作为整个缓存行(64字节)从主内存加载。从L1缓存加载一个字节和加载四个字节之间的差异微不足道。

如果您正在尝试优化非常高性能的应用程序的缓存行,则可能会担心枚举的大小,但一般来说,定义枚举比使用布尔值更清晰。


4

在Java中,这将占用更多的内存。而在C++中,它所占用的内存量与相同类型的常量所需的内存量相同(在编译时计算,运行时没有剩余意义)。在C++中,这意味着枚举的默认类型将占用与int相同的空间。


3

在ISO C++中,枚举类型的大小不一定比其最大枚举值所需的大小大。特别地,即使sizeof(bool)==sizeof(int),enum {TRUE, FALSE}的大小也可能为sizeof(1)。没有任何要求。有些编译器将枚举类型大小设置为与int相同。这是编译器的一个特性,因为标准只强制规定了最小值。其他编译器使用扩展来控制枚举类型的大小。


我认为大多数人使用本机大小来适配CPU架构。对于大多数32位CPU来说,32位对齐的数据检索速度很快,因此大多数类型最终都成为32位的倍数。 - gbjbaanb

1
printf("%d", sizeof(enum));

1
在C++中,枚举类型通常与int类型具有相同的大小。尽管如此,编译器通常会提供一个命令行开关,允许将枚举类型的大小设置为适合定义值范围的最小大小。

0

不,枚举类型通常与 int 类型相同大小,与布尔类型相同。


因此,“通常”情况下可能会这样。但是,如果有人提出这样的问题而没有进一步的细节,那么像这样的边缘情况很少是重要的。 - Serafina Brocious
Java和C++标签表示该评论在此上下文中包含正确的答案。 - Jeffrey L Whitledge
好的,在进一步的研究中,Java的答案似乎是不正确的。(OT:虽然在C#中与int相同。) - Jeffrey L Whitledge
在C++中,枚举和整数相同。布尔值和字符也相同。 - Martin York

0
如果你的枚举类型只有两种情况,使用布尔值可能是更好的选择(内存大小、性能、使用逻辑),特别是在Java中。如果你担心内存成本,那么这可能意味着你计划使用大量的它们。在Java中,你可以使用BitSet类,在两种语言中,你都可以使用位运算来操作位。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接