【发布时间】:2010-09-13 16:26:01
【问题描述】:
例如,如果我有一个包含两种情况的枚举,它是否比布尔值占用更多的内存?语言:Java、C++
【问题讨论】:
例如,如果我有一个包含两种情况的枚举,它是否比布尔值占用更多的内存?语言:Java、C++
【问题讨论】:
在 Java 中,enum is a full-blown class:
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 的每个字段都是Constants enum 类的实例。 (进一步分析javap会发现每个字段都是通过在静态初始化块中调用new Constants(String)构造函数来创建一个新对象来初始化的。)
因此,我们可以看出,我们创建的每个 enum 字段至少与在 JVM 中创建对象的开销一样多。
【讨论】:
在 ISO C++ 中,枚举没有义务大于其最大枚举数所需的大小。特别是,即使在 sizeof(bool)==sizeof(int) 时,枚举 {TRUE, FALSE} 也可能具有 sizeof(1)。根本没有要求。一些编译器使枚举与 int 大小相同。这是一个编译器特性,这是允许的,因为标准只规定了最低限度。其他编译器使用扩展来控制枚举的大小。
【讨论】:
在 C/C++ 中,枚举的大小与 int 相同。
使用 gcc,您可以将 attribute((packed)) 添加到枚举定义中,以使其占用最少的空间。如果枚举中的最大值
typedef enum {
MY_ENUM0,
MY_ENUM1,
MY_ENUM2,
MY_ENUM3,
MY_ENUM4,
MY_ENUM5
} __attribute__((packed)) myEnum_e;
【讨论】:
在 C++ 中,枚举的大小通常与 int 相同。也就是说,编译器提供命令行开关以允许将枚举的大小设置为适合定义的值范围的最小大小的情况并不少见。
【讨论】:
sizeof(enum) 取决于枚举中的内容。我最近试图使用默认构造函数参数查找 ArrayList() 的大小,并且内部没有存储对象(这意味着存储容量为 10)。原来ArrayList并没有太大
因此,一个非常简单的枚举的 sizeof(enum) 应该小于 10 个字节。你可以写一个小程序,给它一定的内存,然后尝试分配枚举。你应该能弄明白(我就是这样找到ArrayList的内存的)
BR,
~A
【讨论】:
只有在存储大量枚举时才会担心这一点。对于 Java,在某些情况下您可能可以使用 EnumSet。它在内部使用位向量,非常节省空间且速度快。
http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html
【讨论】:
在 Java 中,每个枚举值在内存中应该只有一个实例。然后,对枚举的引用只需要该引用的存储空间。检查枚举的值与任何其他参考比较一样有效。
【讨论】:
bool 可以实现为单个字节,但通常在一个结构中,它会被具有对齐要求的其他元素包围,这意味着布尔值将有效地占用至少与int 一样多的空间.
现代处理器从主内存加载数据作为整个高速缓存行,64 字节。从 L1 缓存加载一个字节和加载四个字节之间的差异可以忽略不计。
如果您尝试优化高性能应用程序中的缓存行,那么您可能会担心枚举有多大,但通常我会说定义枚举比使用布尔值更清晰。
【讨论】:
如果您的枚举只有两种情况,那么确实使用布尔值可能是一个更好的主意(内存大小、性能、使用/逻辑),在 Java 中更是如此。
如果您想知道内存成本,这可能意味着您计划使用大量内存。在 Java 中,您可以使用 BitSet 类,或者在较小的范围内,在这两种语言中,您都可以使用按位操作来操作位。
【讨论】:
printf("%d", sizeof(enum));
【讨论】:
在 Java 中,它会占用更多内存。在 C++ 中,它只占用相同类型的常量所需的内存(它在编译时评估,在运行时没有剩余意义)。在 C++ 中,这意味着枚举的默认类型将占用与 int 相同的空间。
【讨论】:
不,枚举通常与 int 大小相同,与 boolean 相同。
【讨论】: