Using RAM management apps in Android which clear the RAM of all applications is, in fact, detrimental to the system and may degrade the performance and battery life instead of conserving battery power.
If an app is stored in the RAM, it consumes battery power.
The truth is- When an app is stored in RAM, the bits in the RAM are held as 1s or 0s accordingly, and the memory is cleared whenever the app is removed. Holding a bit as 0 or 1 takes the same power. There is no effect on the power usage if a bit is held as 1 instead of 0, as this involves only data storage and the kind of bit being stored in that memory location does not matter.
It is the CPU usage that affects the battery life, and not the RAM usage. If an app is present in memory and is consuming a lot of battery power, it indicates a high usage of the processor by the app, possibly as a result of weak code management by the developer of the app. Killing or uninstalling such an app may help to increase battery life, but the cause for this is not RAM usage, rather it is the excessive usage of the CPU.
Each app process is forked from an existing process called Zygote. The Zygote process starts when the system boots and loads common framework code and resources (such as activity themes).
To start a new app process, the system forks the Zygote process then loads and runs the app’s code in the new process. This allows most of the RAM pages allocated for framework code and resources to be shared across all app processes.
Most static data is mmapped into a process. This not only allows that same data to be shared between processes but also allows it to be paged out when needed.
eg. Dalvik code (pre-linked .odex file), app resources, traditional project elements – native code in .so files.
In many places, Android shares the same dynamic RAM across processes using explicitly allocated shared memory regions (either with ashmem or gralloc).
Stack architecture for threads
Dalvik had separate stacks for native and Java code, with a default Java stack size of 32KB and a default native stack size of 1MB. ART has a unified stack for better locality. Ordinarily, the ART Thread stack size should be approximately the same as for Dalvik.
A Thread is a concurrent unit of execution. It has its own call stack for methods being invoked, their arguments and local variables. Each application has at least one thread running when it is started, the main thread, in the main ThreadGroup. The runtime keeps its own threads in the system thread group.
Dalvik uses registers as primary units of data storage instead of the stack. Google is hoping to accomplish 30 percent fewer instructions as a result.
Stack size for threads
The OS allocates the stack for each system-level thread when the thread is created. When the thread exits the stack is reclaimed. The size of the stack is set when a thread is created.
Android’s default stack size is 8KB. This gets you 60-100 stack frames, depending on how complex your methods are.
There appears to be a separate thread (called the HeapWorker) in each VM process that performs the garbage collection actions.
- When the Dalvik heap hits a soft occupancy limit. VM Parameter – InitiatingHeapOccupancyPercent. Default value is 45%.
- When memory allocation for an object fails.
- Just before triggering OutOfMemoryError – full, synchronous garbage collection is done.
- Explicit triggering by calling System.gc()
Android does not defragment the heap to close up space. Android can only shrink the logical heap size when there is unused space at the end of the heap. But this doesn’t mean the physical memory used by the heap can’t shrink. After garbage collection, Dalvik walks the heap and finds unused pages, then returns those pages to the kernel using madvise. (Reclaiming memory from small allocations can be much less efficient because the page used for a small allocation may still be shared with something else that has not yet been freed).
Android Memory Management
Android does not offer swap space for memory, but it does use paging and memory-mapping (mmapping) to manage memory.
This means that any memory you modify—whether by allocating new objects or touching mmapped pages—remains resident in RAM and cannot be paged out. So the only way to completely release memory from your app is to release object references you may be holding, making the memory available to the garbage collector.
That is with one exception: any files mmapped in without modification, such as code, can be paged out of RAM if the system wants to use that memory elsewhere.
Heap Memory Management
Each Android application runs in a separate process within its own Dalvik instance, relinquishing all responsibility for memory and process management to the Android run time, which stops and kills processes as necessary to manage resources.
Why we have a heap: While allocation may be slower than a stack (O(log n) vs O(1)), heaps allow freeing memory at an arbitrary location to be fast – O(log n), compared to a stack’s O(n).
What is Binder?
Binder is an Android-specific mode of achieving IPC (inter-process communication). It is a high-level implementation spanning several layers of the Android software stack. The main implementation can be found in binder.c in the kernel source code.
One Android process can call a routine in another Android process, using binder to identify the method to invoke and pass the arguments between processes.
Some functionalities provided by the Binder IPC are:
- Link of death
Java interface to Binder. Inherited constants – From interface android.os.IBinder.
Public constructor – Binder().
Garbage Collection (GC)
Automatic garbage collection solves problems of explicit memory management – dangling references and space leaks.
- Reference counting
- Tracing algorithms – tri-colour marking scheme (white, black, grey)
- Mark and sweep
GC pointer goes on checking for the live objects and if found it sweeps to the left side of the heap so that a contiguous space is formed.
Avoids repeated collection of objects by dividing the heap into old and young generations. Monitors references from old to young – “Remembered set” – use as roots to collect just young space.
A method of performing GC using semi-spaces, that is, by splitting heap memory into two parts and only using one at a time.
Concurrent Mark-Sweep (CMS) collector
Collection of the old generation is done concurrently with the execution of the application. Initially marks all the live objects.