am de3c20bc: Merge "Track stack memory in MemoryInfo."

* commit 'de3c20bcb546e50980a642b72c1e8353e5bd2cdc':
  Track stack memory in MemoryInfo.
This commit is contained in:
Ian Rogers
2013-02-27 12:06:58 -08:00
committed by Android Git Automerger
2 changed files with 39 additions and 24 deletions

View File

@ -130,7 +130,7 @@ public final class Debug
public int otherSharedDirty; public int otherSharedDirty;
/** @hide */ /** @hide */
public static final int NUM_OTHER_STATS = 9; public static final int NUM_OTHER_STATS = 10;
private int[] otherStats = new int[NUM_OTHER_STATS*3]; private int[] otherStats = new int[NUM_OTHER_STATS*3];
@ -177,15 +177,16 @@ public final class Debug
/* @hide */ /* @hide */
public static String getOtherLabel(int which) { public static String getOtherLabel(int which) {
switch (which) { switch (which) {
case 0: return "Cursor"; case 0: return "Stack";
case 1: return "Ashmem"; case 1: return "Cursor";
case 2: return "Other dev"; case 2: return "Ashmem";
case 3: return ".so mmap"; case 3: return "Other dev";
case 4: return ".jar mmap"; case 4: return ".so mmap";
case 5: return ".apk mmap"; case 5: return ".jar mmap";
case 6: return ".ttf mmap"; case 6: return ".apk mmap";
case 7: return ".dex mmap"; case 7: return ".ttf mmap";
case 8: return "Other mmap"; case 8: return ".dex mmap";
case 9: return "Other mmap";
default: return "????"; default: return "????";
} }
} }

View File

@ -43,6 +43,7 @@ enum {
HEAP_UNKNOWN, HEAP_UNKNOWN,
HEAP_DALVIK, HEAP_DALVIK,
HEAP_NATIVE, HEAP_NATIVE,
HEAP_STACK,
HEAP_CURSOR, HEAP_CURSOR,
HEAP_ASHMEM, HEAP_ASHMEM,
HEAP_UNKNOWN_DEV, HEAP_UNKNOWN_DEV,
@ -109,7 +110,7 @@ static jlong android_os_Debug_getNativeHeapAllocatedSize(JNIEnv *env, jobject cl
static jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz) static jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz)
{ {
#ifdef HAVE_MALLOC_H #ifdef HAVE_MALLOC_H
struct mallinfo info = mallinfo(); struct mallinfo info = mallinfo();
return (jlong) info.fordblks; return (jlong) info.fordblks;
#else #else
@ -164,6 +165,8 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
whichHeap = HEAP_NATIVE; whichHeap = HEAP_NATIVE;
} else if (strstr(name, "/dev/ashmem/dalvik-") == name) { } else if (strstr(name, "/dev/ashmem/dalvik-") == name) {
whichHeap = HEAP_DALVIK; whichHeap = HEAP_DALVIK;
} else if (strstr(name, "[stack") == name) {
whichHeap = HEAP_STACK;
} else if (strstr(name, "/dev/ashmem/CursorWindow") == name) { } else if (strstr(name, "/dev/ashmem/CursorWindow") == name) {
whichHeap = HEAP_CURSOR; whichHeap = HEAP_CURSOR;
} else if (strstr(name, "/dev/ashmem/") == name) { } else if (strstr(name, "/dev/ashmem/") == name) {
@ -191,7 +194,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
//ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap, //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap,
// isSqliteHeap, line); // isSqliteHeap, line);
while (true) { while (true) {
if (fgets(line, 1024, fp) == 0) { if (fgets(line, 1024, fp) == 0) {
done = true; done = true;
@ -233,7 +236,7 @@ static void load_maps(int pid, stats_t* stats)
{ {
char tmp[128]; char tmp[128];
FILE *fp; FILE *fp;
sprintf(tmp, "/proc/%d/smaps", pid); sprintf(tmp, "/proc/%d/smaps", pid);
fp = fopen(tmp, "r"); fp = fopen(tmp, "r");
if (fp == 0) return; if (fp == 0) return;
@ -247,7 +250,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
{ {
stats_t stats[_NUM_HEAP]; stats_t stats[_NUM_HEAP];
memset(&stats, 0, sizeof(stats)); memset(&stats, 0, sizeof(stats));
load_maps(pid, stats); load_maps(pid, stats);
for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) {
@ -261,9 +264,9 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty); env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty);
env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty); env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty);
} }
jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field); jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field);
jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0); jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0);
if (otherArray == NULL) { if (otherArray == NULL) {
return; return;
@ -328,7 +331,7 @@ static jint read_binder_stat(const char* stat)
char compare[128]; char compare[128];
int len = snprintf(compare, 128, "proc %d", getpid()); int len = snprintf(compare, 128, "proc %d", getpid());
// loop until we have the block that represents this process // loop until we have the block that represents this process
do { do {
if (fgets(line, 1024, fp) == 0) { if (fgets(line, 1024, fp) == 0) {
@ -336,15 +339,15 @@ static jint read_binder_stat(const char* stat)
} }
} while (strncmp(compare, line, len)); } while (strncmp(compare, line, len));
// now that we have this process, read until we find the stat that we are looking for // now that we have this process, read until we find the stat that we are looking for
len = snprintf(compare, 128, " %s: ", stat); len = snprintf(compare, 128, " %s: ", stat);
do { do {
if (fgets(line, 1024, fp) == 0) { if (fgets(line, 1024, fp) == 0) {
return -1; return -1;
} }
} while (strncmp(compare, line, len)); } while (strncmp(compare, line, len));
// we have the line, now increment the line ptr to the value // we have the line, now increment the line ptr to the value
char* ptr = line + len; char* ptr = line + len;
return atoi(ptr); return atoi(ptr);
@ -510,7 +513,7 @@ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz,
jobject fileDescriptor) jobject fileDescriptor)
{ {
if (fileDescriptor == NULL) { if (fileDescriptor == NULL) {
jniThrowNullPointerException(env, NULL); jniThrowNullPointerException(env, "fd == null");
return; return;
} }
int origFd = jniGetFDFromFileDescriptor(env, fileDescriptor); int origFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
@ -547,7 +550,7 @@ static void android_os_Debug_dumpNativeBacktraceToFile(JNIEnv* env, jobject claz
jint pid, jstring fileName) jint pid, jstring fileName)
{ {
if (fileName == NULL) { if (fileName == NULL) {
jniThrowNullPointerException(env, NULL); jniThrowNullPointerException(env, "file == null");
return; return;
} }
const jchar* str = env->GetStringCritical(fileName, 0); const jchar* str = env->GetStringCritical(fileName, 0);
@ -611,6 +614,19 @@ int register_android_os_Debug(JNIEnv *env)
{ {
jclass clazz = env->FindClass("android/os/Debug$MemoryInfo"); jclass clazz = env->FindClass("android/os/Debug$MemoryInfo");
// Sanity check the number of other statistics expected in Java matches here.
jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I");
jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field);
int expectedNumOtherStats = _NUM_HEAP - _NUM_CORE_HEAP;
if (numOtherStats != expectedNumOtherStats) {
jniThrowExceptionFmt(env, "java/lang/RuntimeException",
"android.os.Debug.Meminfo.NUM_OTHER_STATS=%d expected %d",
numOtherStats, expectedNumOtherStats);
return JNI_ERR;
}
otherStats_field = env->GetFieldID(clazz, "otherStats", "[I");
for (int i=0; i<_NUM_CORE_HEAP; i++) { for (int i=0; i<_NUM_CORE_HEAP; i++) {
stat_fields[i].pss_field = stat_fields[i].pss_field =
env->GetFieldID(clazz, stat_field_names[i].pss_name, "I"); env->GetFieldID(clazz, stat_field_names[i].pss_name, "I");
@ -620,8 +636,6 @@ int register_android_os_Debug(JNIEnv *env)
env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I"); env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I");
} }
otherStats_field = env->GetFieldID(clazz, "otherStats", "[I");
return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods)); return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods));
} }