Introduction:
The Dalvik vm has its own heap to allocate/de-allocate memory spaces for the newly created java classes. However, the posix doesn't provide interfaces to malloc/free memory spaces within an already set memory region. Therefore, the Dalvik vm uses the doug lea allocator (dlmalloc) to help it. The dlmalloc provide APIs to create a memory region and manage it. By using the dlmalloc, Dalvik vm has a heap to serve the dynamic memory allocation in Java.
1. At the construction step of Dalvik vm, callee: dvmHeapSourceStartup will be called
- file
-- dalvik/vm/alloc/HeapSource.c
- parameter
-- size_t startSize
= gDvm.heapSizeStart = 2 * 1024 * 1024 = 2MB
-- size_t absoluteMaxSize
= gDvm.heapSizeMax = 16 * 1024 * 1024 = 16MB
- return value
-- GcHeap *
2. Then callee: createMspace will be called by caller: dvmHeapSourceStartup
- file
-- dalvik/vm/alloc/HeapSource.c
- parameter
-- size_t startSize
= gDvm.heapSizeStart = 2 * 1024 * 1024 = 2MB
-- size_t absoluteMaxSize
= gDvm.heapSizeMax = 16 * 1024 * 1024 = 16MB
- return value
-- static mspace *
- This function will do
Make the name of the need-to-create heap, and then call the API to create a contiguous memory space as the heap.
3. Then callee: create_contiguous_mspace_with_name will be called by caller: createMspace
- file
-- system/core/libcutils/mspace.c
- parameter
-- size_t starting_capacity
= startSize / 2 = gDvm.heapSizeStart / 2 = 1MB
-- size_t max_capacity
= absoluteMaxSize = gDvm.heapSizeMax = 16MB
-- int locked
= false
-- char const * name
= name generated in createMspace
- return value
-- mspace
- This function will do:
(1). max_capacity = (size_t)ALIGN_UP(max_capacity, pagesize);
set the heap's max size align up to page boundary
#define PAGESIZE 4096 = 4KB
#define ALIGN_UP(p, alignment) (((uintptr_t)(p) + (alignment)-1) & ~((alignment)-1))
(2). fd = ashmem_create_region(buf, max_capacity);
Map the /dev/zero to fd
fd = open("/dev/zero", O_RDWR);
(3). base = mmap(NULL, max_capacity, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
Do mmap() to map the opened file /dev/zero to the memory with length = max_capacity. On Linux, the mapping will be created at a nearby page boundary.This step will create the needed heap for dynamic memory allocation usage.
(4). The following step will make some installation to the mapped memory in order to manage it as mspace.
local variable: struct mspace_contig_state *cs;
struct mspace_contig_state {
unsigned int magic;
char *brk;
char *top;
mspace m;
};
cs = base;
-This will make the cs point to the starting address of the created memory space, then the header of the memory space is cs.
m = create_mspace_with_base(base + sizeof(*cs), starting_capacity, locked);
-This will create the mspace from the mapped memory space.
cs->brk = m->seg.base + m->seg.size;
-This set the current usable size of the mspace, which is initialized to
m->footprint = m->max_footprint = starting_capacity = 1MB
This set the max usable size of the mspace.
if (cs->brk != cs->top) {
/* mprotect() requires page-aligned arguments, but it's possible
* for cs->brk not to be page-aligned at this point.
*/
char *prot_brk = (char *)ALIGN_UP(cs->brk, pagesize);
if (mprotect(prot_brk, cs->top - prot_brk, PROT_NONE) < 0)
goto error;
}
-This step prevents access to the memory Dalvim VM haven't handed out yet.
(5). return (mspace)m;
This step return the mspace pointer to the caller: createMspace
4. Then callee: mspace_set_max_allowed_footprint will be called by caller: createMspace
- parameter
-- mspace msp
= newly created mspace
-- size_t bytes
= startSize = 1MB
- local variable ms = (mstate)msp
-This function will set the current max_allowed_footprint. ms->max_allowed_footprint will be set to msp->footprint. This function will be called later to increase or decrease the
ms->max_allowed_footprint according to the usage of the Dalvik vm heap. If the Dalvik VM needs to grow its heap size, the ms->max_allowed_footprint will be increased.