JVM and ART
Table of contents
Java Virtual Machine (JVM).
Dalvik → Android Runtime (ART).
Garbage Collection
How it works? What optimizations? What impacts on performance? Tools for analysis?
Concepts in JVM (Hotspot implementation) | Concepts in Android VM (ART) |
---|---|
generational GC heap, ie young, old, and permanent | generational GC heap, ie young and old |
concurrent copying (improving GC, reducing background memory usage & fragmentation, see Linux Memory Management) | |
read barrier (improvement in GC implementation detail) | |
Reference: Android 8.0 ART improvements, https://source.android.com/docs/core/runtime/improvements |
Typical process on heap:
Allocation for objects → generational GC triggered → reclaim unused allocation.
Where does GC happen?
Mainly on heap.
What is the priority of allocation places?
Normal objects go to young generation (of heap). Big objects go to old generation. Long-live objects will go to old generation.
How to mark one as garbage, or say decide one need to be reclaim for it is dying?
- Reference counting, count the references of objects, easy but cycle could exist.
- Reachable tracing, trace the reachable objects through a chain of references. The roots of the chain might be objects referenced in local stacks of threads, native method stack, static and constants in method area, synchronized locks, and JNI.
How to reclaim the memory of garbages?
Algorithms like i) mark-and-sweep, ii) copying then sweep, iii) mark-and-compact, iv) generational collection.
Reference: JVM垃圾回收详解,Java内存区域详解,类加载过程
Reference: JVM Specification (SE22) - Chapter 5 Loading, Linking, and Initializing
Reference: Overview of Memory Management, developer.android
Memory Management
Reference: Manage your app’s memory, developer.android.
Reference: 内存管理(Linux),操作系统常见面试题总结-内存管理,JMM(Java内存模型)详解
🫑 Some memory-efficient code suggestions, from developer.android.
Don’t leave unnecessary services running, use them sparingly. Consider
WorkManager
to schedule background processes and persistent works.Use data containers optimized for mobile devices, eg
HashMap
→SparseArray
.Thought abstraction is good for flexibility and reuse? They are costly to be executed too.
Lite protobufs (protocol buffers) would be good on client-side, as they are designed for serializing structural data. Notice regular protobufs would often get verbose.
Memory churn would cause frequent garbage collection, and then would drain the battery faster. It is the number of allocated temporary objects in a given amount of time. Eg create heavy objects like
Bitmap
orPaint
in afor
loop or inonDraw()
of a view might consume the available memory in young generation quickly.Use Memory Profiler (Investigating Your RAM Usage) to inspect the code where remains high memory churn. Consider moving things out of inner loops or moving them into a factory-based allocation structure (Factory method pattern). In some cases, an object pool may help. Evaluate its allocations-savings and other overheads (eg synchronization, lifecycle, capacity) thoroughly to determine if it is really helpful.