Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enum vs. Static Constants, memory footprint

First see the following quote from the Android developer's guide:

  • Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.

  • Every class in Java (including anonymous inner classes) uses about 500 bytes of code. https://developer.android.com/training/articles/memory.html

Despite the ominous warning in the first bullet point to "strictly avoid using enums on Android," what is said under that point actually doesn't sound so bad. Constants are 32 bit integers, and enums are likely 64 bit references. The math given there about enums being twice as expensive makes sense, and doesn't seem so scary.

My concern is that the warning, might in part, be based off the second bullet point.

I am wondering whether a simple enum "class" declaration carries 500 byte overhead? How about eacn enum type?

It seems quite plausible that types could be "extended classes" since they can take their own methods, rather than just instances. To phrase it as a question, if my enum is Color, and I have 20 Color enum types (e.g. red, blue, green...), is that 500 bytes per type?

like image 602
NameSpace Avatar asked Aug 14 '14 10:08

NameSpace


Video Answer


2 Answers

Enums are an ongoing infinite debate in the Android world.

You can hear a good talk from Romain Guy and Chet Haase about it here: http://www.parleys.com/play/5298f999e4b039ad2298c9e3/chapter57/about

According to this video how big is an object in Dalvik can be calculated as:

overhead of Object + overhead of dlmalloc + data + align
  • The overhead of an Object is exactly 8 bytes.
  • The overhead of dlmalloc can be 4 - 8 bytes (most of the times is 8 bytes)
  • The size of the data depends on the data (of course)
  • Finally everything must be 8-byte aligned (for example, if you have 12 bytes for an Object this will take 16 bytes)

Remember to keep in mind that every value of an enum is actually an instance of an Enum class.

Another important point to keep in mind is the dex file size. For example, the following enum will take around 1,112 bytes

public static enum Things {
    THING_1,
    THING_2;
};

Or you can have two static int which will take 128 bytes.

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

You have 10x improvement in the dex file size.

There is also a big different in on how much compiled dalvik code is generated. For Enum there is a lot of stuff the compiler does for you. There is a static class initialization the first time the class is loaded at runtime. It adds overtime at start-up.

On the other hand enum bring also a lot of pros: readability, usability, type safe code. I would worry about enum only in particular extreme cases.

Especially when we consider that using ProGuard can optimize Enums converting them to normal int constants.

like image 168
Luigi Massa Gallerano Avatar answered Sep 21 '22 14:09

Luigi Massa Gallerano


You are miss read the message.

You quote

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

Refer that you need to store the class definition in some place and that takes 500 bytes.

This mean that there is no difference between enum Const {} and class Const{}.

What is more important is how much memory that objects consume when an instance is created.

Every class instance has 12-16 bytes of RAM overhead. - next line form source.

To summary this up. You can benefit form constants in form of int value only when they are declared among same long container (enum or class).

In reality enum is also a class that extend Enum<?> type, and an instance of it requires more memory than static int constant.

What you trade of here is memory consumption and type safe code. When you use int as constant you can not assure type safety.

public void doAction(int what) {}

public void doAction(What what) {}

On modern devices you can code consuming more memory. But for some aspects of your code might be easier to use int for other enums is correct choice. This is especially visible on androind R package where the amount of code is significant.

In such case you should use int for small domain fields enum are more secure.

like image 27
Damian Leszczyński - Vash Avatar answered Sep 20 '22 14:09

Damian Leszczyński - Vash