枚举占用多少内存?

时间:2020-03-06 14:49:17  来源:igfitidea点击:

例如,如果我有一个带有两种情况的枚举,它是否比布尔值占用更多的内存?语言:Java,C ++

解决方案

不,枚举的大小通常与int相同,与boolean相同。

在Java中,"枚举"是一个成熟的类:

Java programming language enum types
  are much more powerful than their
  counterparts in other languages. The
  enum declaration defines a class
  (called an enum type). The enum class
  body can include methods and other
  fields.

为了查看每个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 {};
}

反汇编表明,"枚举"的每个字段都是"常量"枚举类的实例。 (使用javap进行的进一步分析将揭示,通过在静态初始化块中调用new Constants(String)构造函数来创建一个新对象来初始化每个字段。)

因此,我们可以说我们创建的每个"枚举"字段至少与在JVM中创建对象的开销一样多。

在Java中,它将占用更多内存。在C ++中,它所占用的内存不会超过相同类型的常量所需要的内存(它在编译时进行评估,并且在运行时没有任何剩余的意义)。在C ++中,这意味着枚举的默认类型将与int占用相同的空间。

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

如果枚举只有两种情况,那么实际上使用布尔值可能是一个更好的主意(内存大小,性能,使用情况/逻辑),甚至在Java中更是如此。
如果我们想了解内存成本,则可能意味着我们打算使用其中的很多内存。在Java中,我们可以使用BitSet类,或者以较小的比例使用这两种语言,我们可以使用按位操作来操纵位。

"布尔"可以实现为单个字节,但是通常在结构中,它会被具有对齐要求的其他元素包围,这意味着布尔值实际上将至少占用与"整数"相同的空间。

现代处理器从主存储器作为整个缓存行(64字节)加载数据。从L1缓存加载一个字节与加载四个字节之间的差异可以忽略不计。

如果我们要针对性能非常高的应用程序中的缓存行进行优化,则可能会担心枚举的大小,但是通常来说,定义枚举比使用布尔值更清晰。

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

我们仅在存储大量枚举时才会担心此问题。对于Java,在某些情况下我们可以使用EnumSet。它在内部使用位向量,这非常节省空间且速度很快。

http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html

sizeof(enum)取决于我们所拥有的枚举。我最近试图用默认的构造函数参数来查找ArrayList()的大小,并且内部没有存储对象(这意味着存储容量为10)。事实证明,ArrayList小于100个字节不是太大。

因此,一个非常简单的枚举的sizeof(enum)应该小于10个字节。我们可以编写一个小程序,为其分配一定的内存,然后尝试分配枚举。我们应该能够弄清楚(这就是我发现ArrayList的内存的方式)

BR
〜A

在C ++中,枚举的大小通常与int相同。也就是说,编译器提供命令行开关以允许将枚举的大小设置为适合定义的值范围的最小大小并不罕见。

在C / C ++中,枚举的大小将与int相同。

使用gcc可以将attribute((packed))添加到枚举定义中,以使其占用的空间最小。如果枚举中的最大值<256,则为一个字节;如果最大值为<65536,则为两个字节,依此类推。

typedef enum {
    MY_ENUM0,
    MY_ENUM1,
    MY_ENUM2,
    MY_ENUM3,
    MY_ENUM4,
    MY_ENUM5
} __attribute__((packed)) myEnum_e;

在ISO C ++中,没有义务使枚举大于其最大的枚举器所需的大小。特别是,即使sizeof(bool)== sizeof(int),枚举{TRUE,FALSE}也可能具有sizeof(1)。根本没有任何要求。一些编译器使枚举的大小与int相同。这是编译器功能,之所以可以使用,是因为该标准仅规定了最小值。其他编译器使用扩展来控制枚举的大小。