【Android性能优化】避免使用Enum

本文探讨了在Android开发中使用枚举类型相较于静态常量所导致的内存占用增加问题。通过实例对比发现,枚举类型使DEX文件体积显著增大,并在运行时消耗更多内存。文章还深入分析了枚举类型在字节码层面的具体实现。

The price of ENUMs

在StackOverFlow等问答社区常常出现关于在Android系统里面使用枚举类型的性能讨论,关于这一点,Android官方的Training课程里面有下面这样一句话:

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


关于enum的效率,请看下面的讨论。假设我们有这样一份代码,编译之后的dex大小是2556 bytes,在此基础之上,添加一些如下代码,这些代码使用普通static常量相关作为判断值:

 

增加上面那段代码之后,编译成dex的大小是2680 bytes,相比起之前的2556 bytes只增加124 bytes。假如换做使用enum,情况如下:

 

使用enum之后的dex大小是4188 bytes,相比起2556增加了1632 bytes,增长量是使用static int的13倍。不仅仅如此,使用enum,运行时还会产生额外的内存占用,如下图所示:

 

Android官方强烈建议不要在Android程序里面使用到enum。

具体原因是为什么呢?下面我们来对其进行分析分析。

下面定义了4个静态常量:

public static final int RED =0;
public static final int GREEN =1;
public static final int BLACK =2;
public static final int YELLOW =3;
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

如果使用Enum表示如下:

public static enum Color {
    RED, GREEN, BLACK, YELLOW
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

我们对Color类进行反编译,进入项目的bin目录,执行 javap -c Color.class

最终结果如下: 
这里写图片描述 
这里写图片描述

我们对上面的反编译代码进行整理如下:

public final class Color extends java.lang.Enum<Color> {
    public static final Color RED;

    public static final Color GREEN;

    public static final Color BLACK;

    public static final Color YELLOW;

    static {
        RED = new Color("RED", 0);

        GREEN = new Color("GREEN", 1);

        BLACK = new Color("BLACK", 2);

        YELLOW = new Color("YELLOW", 3);

        VALUES = new Color[]{RED, GREEN, BLACK, YELLOW};
    }

    public static Color[] values() {
        Color tmp = new Color[VALUES.length];
        system.arraycopy(VALUES, 0, tmp, 0, VALUES.length);
        return tmp;
    }

    public static Color valueOf(String name) {
        return Enum.valueOf(name);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

上面的代码是根据上面反编译出来的代码编写的,不是标准的,操作过程基本可以呈现。

可以看到,本来是可以使用几个静态常量代替的Color类做了这么多额外的操作,分配了这么多内存,这也是Enum在Android不被建议使用的原因。

从上面的代码可以看到,它其实对上面的几个静态常量做了封装,然后又重新定义了几个静态封装对象,代价非常的大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值