枚举与静态常量,内存占用

时间:2014-08-14 10:12:33

标签: java android enums

首先请参阅Android开发人员指南中的以下引用:

  

尽管第一个要点中的不祥警告是“严格避免在Android上使用枚举”,但在这一点上所说的实际上听起来并不是那么糟糕。常量是32位整数,枚举可能是64位引用。那里给出的关于枚举价格贵两倍的算法是有道理的,而且看起来并不那么可怕。

我担心的是,警告可能部分取决于第二个要点。

我想知道一个简单的枚举“类”声明是否带有500字节的开销? eacn enum类型怎么样?

似乎很有道理,类型可以是“扩展类”,因为它们可以采用自己的方法,而不仅仅是实例。要将它短语作为一个问题,如果我的枚举是Color,并且我有20种颜色枚举类型(例如红色,蓝色,绿色......),那么每种类型是500个字节吗?

2 个答案:

答案 0 :(得分:18)

Enums是Android世界中一直存在的无限争论。

你可以在这里听到Romain Guy和Chet Haase的好话:http://www.parleys.com/play/5298f999e4b039ad2298c9e3/chapter57/about

根据这段视频,达尔维克的物体有多大可以计算为:

overhead of Object + overhead of dlmalloc + data + align
  • Object的开销正好是8个字节。
  • dlmalloc的开销可以是4-8个字节(大多数时间是8个字节) 字节)
  • 数据的大小取决于数据(当然)
  • 最后一切都必须是8字节对齐的(例如,如果你有12个字节 对于一个对象,这将需要16个字节)

请记住,枚举的每个值实际上都是Enum类的实例。

要记住的另一个要点是dex文件大小。 例如,以下枚举将占用大约1,112字节

public static enum Things {
    THING_1,
    THING_2;
};

或者你可以有两个静态int,它将占用128个字节。

public static int THING_1 = 1;
public static int THING_2 = 2;

你的dex文件大小提高了10倍。

生成编译的dalvik代码的数量也有很大差异。 对于Enum,编译器会为您做很多事情。第一次在运行时加载类时会有一个静态类初始化。它在启动时增加了加班时间。

另一方面,枚举也带来了很多优点:可读性,可用性,类型安全代码。 我只会在特殊的极端情况下担心枚举。

特别是当我们考虑使用ProGuard可以优化Enums将它们转换为普通的int常量时。

答案 1 :(得分:2)

你很想念这条消息。

你引用

Every class in Java (including anonymous inner classes) uses about 500 bytes of code.

请参考您需要在某个地方存储类定义,并且需要500个字节。

这意味着enum Const {}class Const{}之间没有区别。

更重要的是创建实例时对象占用的内存量。

Every class instance has 12-16 bytes of RAM overhead. - 下一行表格来源。

总结一下。只有当它们在同一个长容器(枚举或类)中声明时,才能以int值的形式使形式常量受益。

实际上,枚举也是一个扩展Enum<?>类型的类,它的实例需要比静态int常量更多的内存。

您在这里交易的是内存消耗和类型安全代码。当您使用int作为常量时,您无法确保类型安全。

public void doAction(int what) {}

public void doAction(What what) {}

在现代设备上,您可以编码消耗更多内存。但是对于某些方面的代码可能更容易使用int for other enums是正确的选择。这在orroind R包中特别明显,其中代码量很大。

在这种情况下,你应该使用int作为小域字段,枚举更安全。