From: Hiroshi Yamauchi Date: Mon, 15 Jul 2013 21:20:41 +0000 (-0700) Subject: Show size/alloc/free per Dalvik heap space in dumpsys X-Git-Tag: android-x86-4.4-r1~5^2^2^2^2^2^2^2^2^2~1^2^2^2^2~1 X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fdalvik.git;a=commitdiff_plain;h=eeb18914e487b4ae8c8702fc390fd1a360c768ae Show size/alloc/free per Dalvik heap space in dumpsys Add the heap size/alloc/free stats to the Dalvik heap space breakdown section in dumpsys meminfo. Also, now the zygote heap has a distict ashmem region name. Bug: 9532137 Bug: 8266259 (cherry picked from commit 3edfe0b32753309ad7dcccd894239cb0a8aefb85) Change-Id: I9b32727e4211f571a5205b6b7281958514d245d4 --- diff --git a/vm/alloc/HeapSource.cpp b/vm/alloc/HeapSource.cpp index 4d03da1f2..2c0a47489 100644 --- a/vm/alloc/HeapSource.cpp +++ b/vm/alloc/HeapSource.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #define SIZE_MAX UINT_MAX // TODO: get SIZE_MAX from stdint.h @@ -384,6 +385,36 @@ static bool addInitialHeap(HeapSource *hs, mspace msp, size_t maximumSize) } /* + * A helper for addNewHeap(). Remap the new heap so that it will have + * a separate ashmem region with possibly a different name, etc. In + * practice, this is used to give the app heap a separate ashmem + * region from the zygote heap's. + */ +static bool remapNewHeap(HeapSource* hs, Heap* newHeap) +{ + char* newHeapBase = newHeap->base; + size_t rem_size = hs->heapBase + hs->heapLength - newHeapBase; + munmap(newHeapBase, rem_size); + int fd = ashmem_create_region("dalvik-heap", rem_size); + if (fd == -1) { + ALOGE("Unable to create an ashmem region for the new heap"); + return false; + } + void* addr = mmap(newHeapBase, rem_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + int ret = close(fd); + if (addr == MAP_FAILED) { + ALOGE("Unable to map an ashmem region for the new heap"); + return false; + } + if (ret == -1) { + ALOGE("Unable to close fd for the ashmem region for the new heap"); + munmap(newHeapBase, rem_size); + return false; + } + return true; +} + +/* * Adds an additional heap to the heap source. Returns false if there * are too many heaps or insufficient free space to add another heap. */ @@ -421,6 +452,9 @@ static bool addNewHeap(HeapSource *hs) heap.base = base; heap.limit = heap.base + heap.maximumSize; heap.brk = heap.base + morecoreStart; + if (!remapNewHeap(hs, &heap)) { + return false; + } heap.msp = createMspace(base, morecoreStart, hs->minFree); if (heap.msp == NULL) { return false; @@ -575,7 +609,7 @@ GcHeap* dvmHeapSourceStartup(size_t startSize, size_t maximumSize, * among the heaps managed by the garbage collector. */ length = ALIGN_UP_TO_PAGE_SIZE(maximumSize); - base = dvmAllocRegion(length, PROT_NONE, "dalvik-heap"); + base = dvmAllocRegion(length, PROT_NONE, gDvm.zygote ? "dalvik-zygote" : "dalvik-heap"); if (base == NULL) { return NULL; } diff --git a/vm/native/dalvik_system_VMDebug.cpp b/vm/native/dalvik_system_VMDebug.cpp index f6d91a24a..d03f6f44b 100644 --- a/vm/native/dalvik_system_VMDebug.cpp +++ b/vm/native/dalvik_system_VMDebug.cpp @@ -18,6 +18,7 @@ * dalvik.system.VMDebug */ #include "Dalvik.h" +#include "alloc/HeapSource.h" #include "native/InternalNativePriv.h" #include "hprof/Hprof.h" @@ -745,11 +746,50 @@ static void Dalvik_dalvik_system_VMDebug_countInstancesOfClass(const u4* args, } } +/* + * public static native void getHeapSpaceStats(long[] data) + */ +static void Dalvik_dalvik_system_VMDebug_getHeapSpaceStats(const u4* args, + JValue* pResult) +{ + ArrayObject* dataArray = (ArrayObject*) args[0]; + + if (dataArray == NULL || dataArray->length < 6) { + RETURN_VOID(); + } + + jlong* arr = (jlong*)(void*)dataArray->contents; + + int j = 0; + size_t per_heap_allocated[2]; + size_t per_heap_size[2]; + memset(per_heap_allocated, 0, sizeof(per_heap_allocated)); + memset(per_heap_size, 0, sizeof(per_heap_size)); + dvmHeapSourceGetValue(HS_BYTES_ALLOCATED, (size_t*) &per_heap_allocated, 2); + dvmHeapSourceGetValue(HS_FOOTPRINT, (size_t*) &per_heap_size, 2); + jlong heapSize = per_heap_size[0]; + jlong heapUsed = per_heap_allocated[0]; + jlong heapFree = heapSize - heapUsed; + jlong zygoteSize = per_heap_size[1]; + jlong zygoteUsed = per_heap_allocated[1]; + jlong zygoteFree = zygoteSize - zygoteUsed; + arr[j++] = heapSize; + arr[j++] = heapUsed; + arr[j++] = heapFree; + arr[j++] = zygoteSize; + arr[j++] = zygoteUsed; + arr[j++] = zygoteFree; + + RETURN_VOID(); +} + const DalvikNativeMethod dvm_dalvik_system_VMDebug[] = { { "getVmFeatureList", "()[Ljava/lang/String;", Dalvik_dalvik_system_VMDebug_getVmFeatureList }, { "getAllocCount", "(I)I", Dalvik_dalvik_system_VMDebug_getAllocCount }, + { "getHeapSpaceStats", "([J)V", + Dalvik_dalvik_system_VMDebug_getHeapSpaceStats }, { "resetAllocCount", "(I)V", Dalvik_dalvik_system_VMDebug_resetAllocCount }, { "startAllocCounting", "()V",