面试题:都说枚举性能不好,不好在哪里?现在有什么优化的方案如何解决的?
首先我们可能要了解一下枚举,以前看性能优化的文章,都说不要使用枚举,因为枚举占用内存大,占用apk空间大,但是一直也不知道原因。
1
09年谷歌官方视频有说,使用枚举会让apk比原来要大大约13倍的空间。
有人可能会有疑问,你咋知道是13倍呢?
大兄弟,消消气,是不是13倍,我们可以自己新建一个工程,然后打包,然后再加入枚举,然后再打包,两个apk进行比较就知道是不是13倍了。
温馨提示:现在jdk普遍都在1.5之上了,枚举性能不好是好多年之前了,所以你如果要测试,最好把jdk安装在1.1版本上,这样才会有效果。
2
使用枚举不仅仅让apk的包变大,也会让内存上涨,谷歌官方视频说使用枚举会比使用常量要多2倍的内存。
那么这个2倍又是怎么计算出来的呢?
首先我们需要了解我们创建的枚举编译之后是什么样。
public enum SexEnum {
MAN,WOMAN;
}
当我们使用javap编译上边文件之后,得到如下的文件
public final class SexEnum extends Enum {
public static final SexEnum MAN;
public static final SexEnum WOMAN;
private static final SexEnum $VALUES[];
...
}
// 每一个SexEnum对象都有两个属性name和i
public static final String name;
public static final int i;
我们先要了解一下正常来说,基本数据类型/引用数据类型占用多少字节
我们来看下下边这张图
然后需要明白一个java对象所占用的内存的计算方式。
Java对象从整体上可分为三个部分:对象头,实例数据,对象填充.
对象头:存储了对象的hash,GC标记,锁标记,class指针,数组长度等。
对象填充:这个比较简单就是VM要求对象大小必须是8的整数倍。
实例数据: 其实就是上边的那张图,但是这里需要特别说明下,数组所占用的内存是不一样的,还有字符串,具体可看下边的链接。
了解了java对象所占内存之后,我们就能计算出一个常量和一个枚举他两的内存大小比较了。
n个常量,所占内存是4n
n个枚举属性,所占内存是4n+4n+24,所以大概是占用常量的2倍
这里说的不是很清楚,具体可看下边的链接
感谢下边的链接
https://www.jianshu.com/p/9d729c9c94c4
https://www.liaohuqiu.net/cn/posts/android-enum-memory-usage/