OSDN Git Service

Show size/alloc/free per Dalvik heap space in dumpsys
authorHiroshi Yamauchi <yamauchi@google.com>
Mon, 15 Jul 2013 21:20:41 +0000 (14:20 -0700)
committerThe Android Automerger <android-build@android.com>
Thu, 1 Aug 2013 00:28:21 +0000 (17:28 -0700)
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

vm/alloc/HeapSource.cpp
vm/native/dalvik_system_VMDebug.cpp

index 4d03da1..2c0a474 100644 (file)
@@ -17,6 +17,7 @@
 #include <stdint.h>
 #include <sys/mman.h>
 #include <errno.h>
+#include <cutils/ashmem.h>
 
 #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;
     }
index f6d91a2..d03f6f4 100644 (file)
@@ -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",