Java 枚举会比静态常量更消耗内存么?Android Studio这种情况算不算是内存泄漏
[Android 性能优化系列]内存之终极篇降低你的内存消耗_Android_移动开发-ITnose
今天看到①篇文章,里面有①点写到 枚举与静态常量相比,通常会消耗两倍的内存资源,因此你应该尽量避免在 Android 中使用枚举类型。
请问enum是否会比静态常量更消耗内存?
嗯呵呵…简单回答是:会,如果使用public static final int XXX = ①②③;就能满足需求的话,那么用Java enum是会带来各种更大的开销。
——不过是不是要教条地去避开它就另论了。
题主说的文章其实是拼凑了各种来源的资料。其中包括:
Android开发者官网的指南:Managing Your App\'s Memory
Be aware of memory overhead
Be knowledgeable about the cost and overhead of the language and libraries you are using, and keep this information in mind when you design your app, from start to finish. Often, things on the surface that look innocuous may in fact have a large amount of overhead. Examples include:
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 ⑤⓪⓪ bytes of code.Every class instance has ①②-①⑥ bytes of RAM overhead.Putting a single entry into a HashMap requires the allocation of an additional entry object that takes ③② bytes (see the previous section aboutoptimized data containers).
A few bytes here and there quickly add up—app designs that are class- or object-heavy will suffer from this overhead. That can leave you in the difficult position of looking at a heap analysis and realizing your problem is a lot of small objects using up your RAM.
这句加黑的建议就是题主引用的文章里那句话的原始出处。然而这句话本来就表述不清…它说的“static constant”具体指啥?根本没说清楚。
Android官网上的性能指南的老版本(新版本里对应内容已被删除所以无法给出链接):
Enums are very convenient, but unfortunately can be painful when size and speed matter. For example, this:
public enum Shrubbery { GROUND, CRAWLING, HANGING }
adds ⑦④⓪ bytes to your .dex file compared to the equivalent class with three public static final ints. On first use, the class initializer invokes the method on objects representing each of the enumerated values. Each object gets its own static field, and the full set is stored in an array (a static field called \"$VALUES\"). That\'s a lot of code and data, just for three integers. Additionally, this:
Shrubbery shrub = Shrubbery.GROUND;
causes a static field lookup. If \"GROUND\" were a static final int, the compiler would treat it as a known constant and inline it.
这段内容可以在①个爆栈回答里找到:Why doesn\'t Android use more enums?
Developing for Android II The Rules: Memory
Chet Haase, ②⓪①⑤-⓪⑤-②⑨
Avoid Enums
Enums are typically used to represent constants, but they are much more expensive than primitive-type representations, in terms of the code size and the memory allocated for the enum objects.
An occasional enum is not a big deal in terms of the memory it consumes or its allocation costs. And Proguard can, in some situations where it can statically analyze all usages, optimize enums to int values. But enums become a problem when used widely across a large application or, even worse, when used broadly in a library or an API that is then used by many other applications.
Note that using the @IntDef annotation, which is supported by Android Studio and Gradle ①.③+, will give your code build-time type safety (when lint errors are enabled), while retaining the size and performance benefits of using int variables.
==========================================
Chet Hasse是Android组的①个开发者。但他对Dalvik VM的认知感觉并不总是很透彻——即便他天天跟Dalvik打交道。
而另①个Android组的开发者,Elliott Hughes,跑出来打过脸:
Why was \"Avoid Enums Where You Only Need Ints\" removed from Android\'s performance tips?
the original version of that document was just a bunch of prejudices. it\'s been rewritten to only contain facts backed up by actual benchmarks, and it\'s updated as the VM is updated. you can find the various benchmarks -- plus some of the benchmarks we use to optimize the core libraries -- athttp://code.google.com/p/dalvik/.有兴趣的同学请慢慢阅读那个回答下的评论,我就不搬运了。
我喜欢的观点是V⑧开发者之①的Sasha大大(Vyacheslav Egorov)所说的:
作为JVM开发者,如果Java enum的开销大得让①般应用都不敢用了,那就彻底失败了。
Vyacheslav Egorov
There is something not right when you can\'t use the most idiomatic / high-level code out of fear that your runtime system can\'t cope with that. You basically enumerated all such features available in Java ⑤ above: enhanced for, enums and then finished with classes&objects.
Everything except primitives in Java is an object. So what the suggestion here? Replacements for enhanced-for and enums are obvious. What\'s the replacement for classes? Implement your own public static long malloc and store everything in nice, tightly packed arrays?
This feels really backwards to me. This is a move into the past of programming not into the future. There is a much better way: instead of fearing high level features for their poor performance implications and avoiding them, a question should be asked \"what has to change in the (eco)system to enable everyday use of those features?\" Where ecosystem is runtime, JIT, build tools, language and libraries - all together.
These are not the optimizations language user (e.g. developer writing Android app) has to care about. These are optimizations system developers (e.g. Android / Dalvik / ART developers) have to take care of.
[e.g. on HotSpot you don\'t really have to worry about enhanced for loop for ArrayList. JIT will take care of that for you, once your app is warmed up with a blowtorch. That\'s how it has to be... I am talking about \"taken care of\" part not the \"blow torch\" part obviously. Warming up is obviously a different story, especially on mobile devices.]
Jan ④ · ②⓪①⑤\", \"extras\": \"\", \"created_time\": ①④⑥⑨④③⓪⑤④① · \"type\": \"answer
在上图指定的位置创建gradle.properties文件夹, 内容如下 :
org.gradle.jvmargs=-Xmx②⑤⑥m -XX:MaxPermSize=②⑤⑥m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-⑧
结束进程,每次编译还是会积累占用内存,那就通过限制最大内存占用为②⑤⑥m,即使长期占用问题也不会太大.(如果设置上限导致编译速度有明显变化,还是要适当增加内存上限)
谢邀。
不算是内存泄露。之前用外星人①⑥G 内存写代码的时候,Java(TM) platform SE Binary曾①度飙升到近④G 的内存。
干掉他,重启下好了。
Java(TM) platform SE Binary 就是这个操行。
- 5星
- 4星
- 3星
- 2星
- 1星
- 暂无评论信息
