[英]How much memory do Enums take?
例如,如果我有一个包含两种情况的枚举,它是否会占用比布尔值更多的内存? 语言:Java,C ++
在Java中, enum
是一个完整的类 :
Java编程语言枚举类型比其他语言中的对应类型更强大。 枚举声明定义了一个类(称为枚举类型)。 枚举类主体可以包括方法和其他字段。
为了查看每个enum
的实际大小,让我们创建一个实际的enum
并检查它创建的class
文件的内容。
假设我们有以下Constants
枚举类:
public enum Constants {
ONE,
TWO,
THREE;
}
使用javap
编译上面的enum
和反汇编生成的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中创建对象的开销一样多。
在Java中,内存中每个枚举值只应该有一个实例。 然后,对枚举的引用仅需要该引用的存储。 检查枚举的值与任何其他参考比较一样有效。
存储大量枚举时,您只会担心这一点。 对于Java,您可以在某些情况下使用EnumSet。 它在内部使用位向量,非常节省空间和快速。
http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html
bool
可以实现为单个字节,但通常在结构中它将被具有对齐要求的其他元素包围,这意味着布尔值实际上将占用至少与int
一样多的空间。
现代处理器从主存储器加载数据作为整个高速缓存行,64字节。 从L1高速缓存加载一个字节和加载四个字节之间的区别可以忽略不计。
如果你试图在一个非常高性能的应用程序中优化缓存行,那么你可能会担心你的枚举有多大,但通常我会说定义一个枚举比使用一个布尔值更清楚。
在Java中,需要更多内存。 在C ++中,它不需要相同类型的常量所需的内存(它在编译时计算并且在运行时没有剩余重要性)。 在C ++中,这意味着枚举的默认类型将占用与int相同的空间。
在ISO C ++中,枚举没有义务大于其最大的枚举器要求。 特别是,即使sizeof(bool)== sizeof(int),枚举{TRUE,FALSE}也可能具有sizeof(1)。 根本没有要求。 有些编译器使枚举的大小与int相同。 这是一个编译器功能,这是允许的,因为标准只强加了最小值。 其他编译器使用扩展来控制枚举的大小。
printf("%d", sizeof(enum));
在C ++中,枚举通常与int
大小相同。 这就是说编译器提供命令行开关以允许将枚举的大小设置为适合定义的值范围的最小大小并不罕见。
不,枚举通常与int的大小相同,与布尔值相同。
如果你的枚举只有两种情况,那么确实使用布尔值可能是一个更好的想法(内存大小,性能,用法/逻辑),甚至更多用Java。
如果你想知道内存成本,可能意味着你计划使用它们。 在Java中,您可以使用BitSet类,或者在较小的范围内,在两种语言中都可以使用按位运算来操作位。
sizeof(enum)取决于你在枚举中的含义。 我最近试图使用默认构造函数params找到ArrayList()的大小,并且没有存储在其中的对象(这意味着存储的容量是10)。 原来,ArrayList不是太大<100字节。
因此,一个非常简单的枚举的sizeof(enum)应小于10个字节。 你可以编写一个小程序,给它一定的内存,然后尝试分配枚举。 你应该能够搞清楚(这就是我如何找到ArrayList的内存)
BR,
〜一
在C / C ++中,枚举与int的大小相同。
使用gcc,您可以将属性 ((packed))添加到枚举定义中,以使其占用最少的空间。 如果枚举中的最大值<256,则这将是一个字节,如果最大值<65536,则为两个字节,等等。
typedef enum {
MY_ENUM0,
MY_ENUM1,
MY_ENUM2,
MY_ENUM3,
MY_ENUM4,
MY_ENUM5
} __attribute__((packed)) myEnum_e;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.