19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define LOG_TAG "android.os.Debug" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 20f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn#include <utils/String8.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h" 22f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn#include "cutils/debugger.h" 235b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski#include <memtrack/memtrack.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2587eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include <cutils/log.h> 26f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn#include <fcntl.h> 27853940331ff2be48ed3e63f459845e5e43d0a131Mark Salyzyn#include <inttypes.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <time.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/time.h> 3406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#include <errno.h> 3506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#include <assert.h> 360e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn#include <ctype.h> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <malloc.h> 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 450e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornenum { 460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN, 470e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_DALVIK, 480e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_NATIVE, 49184293076201ec510898f8d505a8fe50458d9604Dianne Hackborn 5064770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn HEAP_DALVIK_OTHER, 517c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers HEAP_STACK, 520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_CURSOR, 530e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_ASHMEM, 54184293076201ec510898f8d505a8fe50458d9604Dianne Hackborn HEAP_GL_DEV, 550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN_DEV, 560e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_SO, 570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_JAR, 580e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_APK, 590e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_TTF, 600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_DEX, 618884ef4fe80505bc6e41c167b67efbb93e43475dAnwar Ghuloum HEAP_OAT, 6288887d0a53f866e61a7524b0edfc95e6dde57d72Anwar Ghuloum HEAP_ART, 630e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN_MAP, 645b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski HEAP_GRAPHICS, 655b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski HEAP_GL, 665b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski HEAP_OTHER_MEMTRACK, 6764770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn 683c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum HEAP_DALVIK_NORMAL, 693c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum HEAP_DALVIK_LARGE, 703c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum HEAP_DALVIK_LINEARALLOC, 713c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum HEAP_DALVIK_ACCOUNTING, 723c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum HEAP_DALVIK_CODE_CACHE, 7325c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier HEAP_DALVIK_ZYGOTE, 7425c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier HEAP_DALVIK_NON_MOVING, 7525c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier HEAP_DALVIK_INDIRECT_REFERENCE_TABLE, 760e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 770e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn _NUM_HEAP, 785b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski _NUM_EXCLUSIVE_HEAP = HEAP_OTHER_MEMTRACK+1, 790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn _NUM_CORE_HEAP = HEAP_NATIVE+1 800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 810e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 820e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstruct stat_fields { 830e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID pss_field; 843c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum jfieldID pssSwappable_field; 850e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID privateDirty_field; 860e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID sharedDirty_field; 873c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum jfieldID privateClean_field; 883a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum jfieldID sharedClean_field; 898883ced18ac25199330843964634fdf70647a127Dianne Hackborn jfieldID swappedOut_field; 900e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 910e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 920e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstruct stat_field_names { 930e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* pss_name; 943c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum const char* pssSwappable_name; 950e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* privateDirty_name; 960e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* sharedDirty_name; 973c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum const char* privateClean_name; 983a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum const char* sharedClean_name; 998883ced18ac25199330843964634fdf70647a127Dianne Hackborn const char* swappedOut_name; 1000e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 1010e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 1020e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstatic stat_fields stat_fields[_NUM_CORE_HEAP]; 1030e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 1040e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstatic stat_field_names stat_field_names[_NUM_CORE_HEAP] = { 1058883ced18ac25199330843964634fdf70647a127Dianne Hackborn { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", 1068883ced18ac25199330843964634fdf70647a127Dianne Hackborn "otherPrivateClean", "otherSharedClean", "otherSwappedOut" }, 1078883ced18ac25199330843964634fdf70647a127Dianne Hackborn { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", 1088883ced18ac25199330843964634fdf70647a127Dianne Hackborn "dalvikPrivateClean", "dalvikSharedClean", "dalvikSwappedOut" }, 1098883ced18ac25199330843964634fdf70647a127Dianne Hackborn { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", 1108883ced18ac25199330843964634fdf70647a127Dianne Hackborn "nativePrivateClean", "nativeSharedClean", "nativeSwappedOut" } 1110e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 1120e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 1130e3328fbdd3845b0e2bec364e951498eaee6b079Dianne HackbornjfieldID otherStats_field; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1155b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinskistatic bool memtrackLoaded; 1165b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct stats_t { 1180e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int pss; 1193c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum int swappablePss; 1200e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int privateDirty; 1210e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int sharedDirty; 1223c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum int privateClean; 1233a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum int sharedClean; 1248883ced18ac25199330843964634fdf70647a127Dianne Hackborn int swappedOut; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define BINDER_STATS "/proc/binder/stats" 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz) 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.usmblks; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapAllocatedSize(JNIEnv *env, jobject clazz) 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.uordblks; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz) 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1517c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers#ifdef HAVE_MALLOC_H 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.fordblks; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1595b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski// Container used to retrieve graphics memory pss 1605b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinskistruct graphics_memory_pss 16137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn{ 1625b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int graphics; 1635b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int gl; 1645b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int other; 1655b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski}; 16637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 1675b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski/* 1685b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski * Uses libmemtrack to retrieve graphics memory that the process is using. 1695b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski * Any graphics memory reported in /proc/pid/smaps is not included here. 1705b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski */ 171cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackbornstatic int read_memtrack_memory(struct memtrack_proc* p, int pid, 172cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn struct graphics_memory_pss* graphics_mem) 1735b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski{ 1745b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int err = memtrack_proc_get(p, pid); 1755b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (err != 0) { 176cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn ALOGW("failed to get memory consumption info: %d", err); 1775b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return err; 17837c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 17937c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 1805b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski ssize_t pss = memtrack_proc_graphics_pss(p); 1815b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (pss < 0) { 1820c6bc73c5e12dd4caae5bf3acbf1d26c3a9ad130Colin Cross ALOGW("failed to get graphics pss: %zd", pss); 1835b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return pss; 1845b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 1855b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski graphics_mem->graphics = pss / 1024; 18637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 1875b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski pss = memtrack_proc_gl_pss(p); 1885b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (pss < 0) { 1890c6bc73c5e12dd4caae5bf3acbf1d26c3a9ad130Colin Cross ALOGW("failed to get gl pss: %zd", pss); 1905b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return pss; 1915b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 1925b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski graphics_mem->gl = pss / 1024; 19337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 1945b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski pss = memtrack_proc_other_pss(p); 1955b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (pss < 0) { 1960c6bc73c5e12dd4caae5bf3acbf1d26c3a9ad130Colin Cross ALOGW("failed to get other pss: %zd", pss); 1975b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return pss; 1985b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 1995b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski graphics_mem->other = pss / 1024; 20037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 2015b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return 0; 2025b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski} 20337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 2045b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski/* 2055b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski * Retrieves the graphics memory that is unaccounted for in /proc/pid/smaps. 2065b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski */ 2075b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinskistatic int read_memtrack_memory(int pid, struct graphics_memory_pss* graphics_mem) 2085b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski{ 2095b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (!memtrackLoaded) { 2105b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return -1; 21137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 21237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 2135b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski struct memtrack_proc* p = memtrack_proc_new(); 2145b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (p == NULL) { 215cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn ALOGW("failed to create memtrack_proc"); 2165b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return -1; 2175b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 21837c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 2195b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int err = read_memtrack_memory(p, pid, graphics_mem); 2205b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski memtrack_proc_destroy(p); 2215b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return err; 22237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn} 22337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void read_mapinfo(FILE *fp, stats_t* stats) 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char line[1024]; 2270e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int len, nameLen; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool skip, done = false; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2303c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum unsigned size = 0, resident = 0, pss = 0, swappable_pss = 0; 2313c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum float sharing_proportion = 0.0; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned shared_clean = 0, shared_dirty = 0; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned private_clean = 0, private_dirty = 0; 2348883ced18ac25199330843964634fdf70647a127Dianne Hackborn unsigned swapped_out = 0; 2353c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum bool is_swappable = false; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned referenced = 0; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned temp; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2390c6bc73c5e12dd4caae5bf3acbf1d26c3a9ad130Colin Cross uint64_t start; 2400c6bc73c5e12dd4caae5bf3acbf1d26c3a9ad130Colin Cross uint64_t end = 0; 2410c6bc73c5e12dd4caae5bf3acbf1d26c3a9ad130Colin Cross uint64_t prevEnd = 0; 2420e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn char* name; 2430e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int name_pos; 2440e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 2450e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int whichHeap = HEAP_UNKNOWN; 2463c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum int subHeap = HEAP_UNKNOWN; 2470e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int prevHeap = HEAP_UNKNOWN; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2490e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if(fgets(line, sizeof(line), fp) == 0) return; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!done) { 2520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn prevHeap = whichHeap; 2530e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn prevEnd = end; 2540e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN; 2553c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum subHeap = HEAP_UNKNOWN; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project skip = false; 2573c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = false; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = strlen(line); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len < 1) return; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project line[--len] = 0; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2630c6bc73c5e12dd4caae5bf3acbf1d26c3a9ad130Colin Cross if (sscanf(line, "%" SCNx64 "-%" SCNx64 " %*s %*x %*x:%*x %*d%n", &start, &end, &name_pos) != 2) { 2640e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn skip = true; 2650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else { 2660e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn while (isspace(line[name_pos])) { 2670e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn name_pos += 1; 2680e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 2690e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn name = line + name_pos; 2700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn nameLen = strlen(name); 2710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 27264770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn if ((strstr(name, "[heap]") == name)) { 2730e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_NATIVE; 27464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strncmp(name, "/dev/ashmem", 11) == 0) { 27564770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn if (strncmp(name, "/dev/ashmem/dalvik-", 19) == 0) { 27664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_DALVIK_OTHER; 27764770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) { 27864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn subHeap = HEAP_DALVIK_LINEARALLOC; 279eee9764418d13176c9671e453775d476c2206f6cMathieu Chartier } else if ((strstr(name, "/dev/ashmem/dalvik-alloc space") == name) || 28025c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier (strstr(name, "/dev/ashmem/dalvik-main space") == name)) { 281eee9764418d13176c9671e453775d476c2206f6cMathieu Chartier // This is the regular Dalvik heap. 282eee9764418d13176c9671e453775d476c2206f6cMathieu Chartier whichHeap = HEAP_DALVIK; 283eee9764418d13176c9671e453775d476c2206f6cMathieu Chartier subHeap = HEAP_DALVIK_NORMAL; 284eee9764418d13176c9671e453775d476c2206f6cMathieu Chartier } else if (strstr(name, "/dev/ashmem/dalvik-large object space") == name) { 28564770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_DALVIK; 28664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn subHeap = HEAP_DALVIK_LARGE; 28725c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier } else if (strstr(name, "/dev/ashmem/dalvik-non moving space") == name) { 28825c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier whichHeap = HEAP_DALVIK; 28925c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier subHeap = HEAP_DALVIK_NON_MOVING; 29025c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier } else if (strstr(name, "/dev/ashmem/dalvik-zygote space") == name) { 29125c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier whichHeap = HEAP_DALVIK; 29225c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier subHeap = HEAP_DALVIK_ZYGOTE; 29325c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier } else if (strstr(name, "/dev/ashmem/dalvik-indirect ref") == name) { 29425c5e2b12d5d5d06739e3f70a0da968d97935b46Mathieu Chartier subHeap = HEAP_DALVIK_INDIRECT_REFERENCE_TABLE; 29564770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) { 29664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn subHeap = HEAP_DALVIK_CODE_CACHE; 29764770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else { 298eee9764418d13176c9671e453775d476c2206f6cMathieu Chartier subHeap = HEAP_DALVIK_ACCOUNTING; // Default to accounting. 29964770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } 30064770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strncmp(name, "/dev/ashmem/CursorWindow", 24) == 0) { 30164770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_CURSOR; 30264770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strncmp(name, "/dev/ashmem/libc malloc", 23) == 0) { 30364770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_NATIVE; 30464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else { 30564770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_ASHMEM; 30664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } 307cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross } else if (strncmp(name, "[anon:libc_malloc]", 18) == 0) { 3080e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_NATIVE; 30964770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strncmp(name, "[stack", 6) == 0) { 3107c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers whichHeap = HEAP_STACK; 31164770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strncmp(name, "/dev/", 5) == 0) { 312184293076201ec510898f8d505a8fe50458d9604Dianne Hackborn if (strncmp(name, "/dev/kgsl-3d0", 13) == 0) { 313184293076201ec510898f8d505a8fe50458d9604Dianne Hackborn whichHeap = HEAP_GL_DEV; 314184293076201ec510898f8d505a8fe50458d9604Dianne Hackborn } else { 315184293076201ec510898f8d505a8fe50458d9604Dianne Hackborn whichHeap = HEAP_UNKNOWN_DEV; 316184293076201ec510898f8d505a8fe50458d9604Dianne Hackborn } 3170e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) { 3180e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_SO; 3193c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 3200e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".jar") == 0) { 3210e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_JAR; 3223c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 3230e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".apk") == 0) { 3240e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_APK; 3253c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 3260e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) { 3270e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_TTF; 3283c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 3299f8589c31f8910a9c3c33a81675822da9f0cf2dfIan Rogers } else if ((nameLen > 4 && strcmp(name+nameLen-4, ".dex") == 0) || 3309f8589c31f8910a9c3c33a81675822da9f0cf2dfIan Rogers (nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) { 3310e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_DEX; 3323c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 3338884ef4fe80505bc6e41c167b67efbb93e43475dAnwar Ghuloum } else if (nameLen > 4 && strcmp(name+nameLen-4, ".oat") == 0) { 3348884ef4fe80505bc6e41c167b67efbb93e43475dAnwar Ghuloum whichHeap = HEAP_OAT; 3353c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 33688887d0a53f866e61a7524b0edfc95e6dde57d72Anwar Ghuloum } else if (nameLen > 4 && strcmp(name+nameLen-4, ".art") == 0) { 33788887d0a53f866e61a7524b0edfc95e6dde57d72Anwar Ghuloum whichHeap = HEAP_ART; 3383c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 339cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross } else if (strncmp(name, "[anon:", 6) == 0) { 340cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross whichHeap = HEAP_UNKNOWN; 3410e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 0) { 3420e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN_MAP; 3430e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (start == prevEnd && prevHeap == HEAP_SO) { 3440e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn // bss section of a shared library. 3450e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_SO; 3460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3496215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap, 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // isSqliteHeap, line); 3517c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 3528883ced18ac25199330843964634fdf70647a127Dianne Hackborn shared_clean = 0; 3538883ced18ac25199330843964634fdf70647a127Dianne Hackborn shared_dirty = 0; 3548883ced18ac25199330843964634fdf70647a127Dianne Hackborn private_clean = 0; 3558883ced18ac25199330843964634fdf70647a127Dianne Hackborn private_dirty = 0; 3568883ced18ac25199330843964634fdf70647a127Dianne Hackborn swapped_out = 0; 3578883ced18ac25199330843964634fdf70647a127Dianne Hackborn 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project done = true; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3648883ced18ac25199330843964634fdf70647a127Dianne Hackborn if (line[0] == 'S' && sscanf(line, "Size: %d kB", &temp) == 1) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = temp; 3668883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'R' && sscanf(line, "Rss: %d kB", &temp) == 1) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resident = temp; 3688883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'P' && sscanf(line, "Pss: %d kB", &temp) == 1) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pss = temp; 3708883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'S' && sscanf(line, "Shared_Clean: %d kB", &temp) == 1) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shared_clean = temp; 3728883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'S' && sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shared_dirty = temp; 3748883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'P' && sscanf(line, "Private_Clean: %d kB", &temp) == 1) { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private_clean = temp; 3768883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'P' && sscanf(line, "Private_Dirty: %d kB", &temp) == 1) { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private_dirty = temp; 3788883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'R' && sscanf(line, "Referenced: %d kB", &temp) == 1) { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenced = temp; 3808883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'S' && sscanf(line, "Swap: %d kB", &temp) == 1) { 3818883ced18ac25199330843964634fdf70647a127Dianne Hackborn swapped_out = temp; 3820c6bc73c5e12dd4caae5bf3acbf1d26c3a9ad130Colin Cross } else if (sscanf(line, "%" SCNx64 "-%" SCNx64 " %*s %*x %*x:%*x %*d", &start, &end) == 2) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // looks like a new mapping 384bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba // example: "10000000-10001000 ---p 10000000 00:00 0" 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!skip) { 3903c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum if (is_swappable && (pss > 0)) { 3913c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum sharing_proportion = 0.0; 3923c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum if ((shared_clean > 0) || (shared_dirty > 0)) { 3938883ced18ac25199330843964634fdf70647a127Dianne Hackborn sharing_proportion = (pss - private_clean 3948883ced18ac25199330843964634fdf70647a127Dianne Hackborn - private_dirty)/(shared_clean+shared_dirty); 3953c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum } 3963c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum swappable_pss = (sharing_proportion*shared_clean) + private_clean; 3973c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum } else 3983c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum swappable_pss = 0; 3993c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum 4000e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].pss += pss; 4013c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[whichHeap].swappablePss += swappable_pss; 4020e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].privateDirty += private_dirty; 4030e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].sharedDirty += shared_dirty; 4043c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[whichHeap].privateClean += private_clean; 4053a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum stats[whichHeap].sharedClean += shared_clean; 4068883ced18ac25199330843964634fdf70647a127Dianne Hackborn stats[whichHeap].swappedOut += swapped_out; 40764770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) { 4083c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].pss += pss; 4093c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].swappablePss += swappable_pss; 4103c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].privateDirty += private_dirty; 4113c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].sharedDirty += shared_dirty; 4123c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].privateClean += private_clean; 4133c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].sharedClean += shared_clean; 4148883ced18ac25199330843964634fdf70647a127Dianne Hackborn stats[subHeap].swappedOut += swapped_out; 4153c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void load_maps(int pid, stats_t* stats) 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char tmp[128]; 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FILE *fp; 4247c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(tmp, "/proc/%d/smaps", pid); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fp = fopen(tmp, "r"); 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fp == 0) return; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project read_mapinfo(fp, stats); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fclose(fp); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4333025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, 4343025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn jint pid, jobject object) 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4360e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats_t stats[_NUM_HEAP]; 4370e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn memset(&stats, 0, sizeof(stats)); 4387c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 4390e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn load_maps(pid, stats); 4400e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 4415b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski struct graphics_memory_pss graphics_mem; 4425b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (read_memtrack_memory(pid, &graphics_mem) == 0) { 4435b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_GRAPHICS].pss = graphics_mem.graphics; 4445b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_GRAPHICS].privateDirty = graphics_mem.graphics; 4455b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_GL].pss = graphics_mem.gl; 4465b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_GL].privateDirty = graphics_mem.gl; 4475b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_OTHER_MEMTRACK].pss = graphics_mem.other; 4485b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_OTHER_MEMTRACK].privateDirty = graphics_mem.other; 4495b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 45037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 4513c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) { 4520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].pss += stats[i].pss; 4533c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss; 4540e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty; 4550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty; 4563c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean; 4573a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean; 4588883ced18ac25199330843964634fdf70647a127Dianne Hackborn stats[HEAP_UNKNOWN].swappedOut += stats[i].swappedOut; 4590e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4610e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=0; i<_NUM_CORE_HEAP; i++) { 4620e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss); 4633c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss); 4640e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty); 4650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty); 4663c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean); 4673a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean); 4688883ced18ac25199330843964634fdf70647a127Dianne Hackborn env->SetIntField(object, stat_fields[i].swappedOut_field, stats[i].swappedOut); 4690e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 4707c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 4713c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum 4720e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field); 4737c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 4740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0); 4750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if (otherArray == NULL) { 4760e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn return; 4770e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 4780e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 4790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int j=0; 4800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { 4810e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].pss; 4823c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum otherArray[j++] = stats[i].swappablePss; 4830e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].privateDirty; 4840e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].sharedDirty; 4853c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum otherArray[j++] = stats[i].privateClean; 4863a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum otherArray[j++] = stats[i].sharedClean; 4878883ced18ac25199330843964634fdf70647a127Dianne Hackborn otherArray[j++] = stats[i].swappedOut; 4880e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 4890e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 4900e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4933025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object) 4943025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn{ 4953025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object); 4963025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn} 4973025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn 4981a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackbornstatic jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jlongArray outUss, 4991a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn jlongArray outMemtrack) 500b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn{ 501b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn char line[1024]; 502b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn jlong pss = 0; 503c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn jlong uss = 0; 5041a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn jlong memtrack = 0; 505b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn unsigned temp; 506b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 507b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn char tmp[128]; 508b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn FILE *fp; 509b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 5105b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski struct graphics_memory_pss graphics_mem; 5115b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (read_memtrack_memory(pid, &graphics_mem) == 0) { 5121a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn pss = uss = memtrack = graphics_mem.graphics + graphics_mem.gl + graphics_mem.other; 5135b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 51437c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 515b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn sprintf(tmp, "/proc/%d/smaps", pid); 516b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn fp = fopen(tmp, "r"); 517b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 51837c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn if (fp != 0) { 51937c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn while (true) { 52037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn if (fgets(line, 1024, fp) == NULL) { 52137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn break; 52237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 523b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 52437c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn if (line[0] == 'P') { 52537c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn if (strncmp(line, "Pss:", 4) == 0) { 52637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn char* c = line + 4; 52737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn while (*c != 0 && (*c < '0' || *c > '9')) { 52837c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn c++; 52937c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 53037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn pss += atoi(c); 53145838de942b87150fc3b03a8b943841a8647fd81Iliyan Malchev } else if (strncmp(line, "Private_Clean:", 14) == 0 53245838de942b87150fc3b03a8b943841a8647fd81Iliyan Malchev || strncmp(line, "Private_Dirty:", 14) == 0) { 53337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn char* c = line + 14; 53437c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn while (*c != 0 && (*c < '0' || *c > '9')) { 53537c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn c++; 53637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 53737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn uss += atoi(c); 538c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn } 539cfc837f7fa43362b5049f648fe1bfdf5a010cc1cDianne Hackborn } 540b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn } 541b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 54237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn fclose(fp); 543b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn } 544b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 545c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn if (outUss != NULL) { 546c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn if (env->GetArrayLength(outUss) >= 1) { 547c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn jlong* outUssArray = env->GetLongArrayElements(outUss, 0); 548c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn if (outUssArray != NULL) { 549c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn outUssArray[0] = uss; 550c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn } 551c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn env->ReleaseLongArrayElements(outUss, outUssArray, 0); 552c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn } 553c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn } 554b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 5551a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn if (outMemtrack != NULL) { 5561a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn if (env->GetArrayLength(outMemtrack) >= 1) { 5571a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn jlong* outMemtrackArray = env->GetLongArrayElements(outMemtrack, 0); 5581a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn if (outMemtrackArray != NULL) { 5591a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn outMemtrackArray[0] = memtrack; 5601a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn } 5611a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn env->ReleaseLongArrayElements(outMemtrack, outMemtrackArray, 0); 5621a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn } 5631a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn } 5641a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn 565b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn return pss; 566b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn} 567b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 568b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackbornstatic jlong android_os_Debug_getPss(JNIEnv *env, jobject clazz) 569b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn{ 5701a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn return android_os_Debug_getPssPid(env, clazz, getpid(), NULL, NULL); 571b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn} 572b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 573cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackbornenum { 574cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_TOTAL, 575cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_FREE, 576cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_BUFFERS, 577cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_CACHED, 578cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_SHMEM, 579cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_SLAB, 580cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_SWAP_TOTAL, 581cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_SWAP_FREE, 582cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_ZRAM_TOTAL, 583b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn MEMINFO_MAPPED, 584b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn MEMINFO_VMALLOC_USED, 585b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn MEMINFO_PAGE_TABLES, 586b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn MEMINFO_KERNEL_STACK, 587cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_COUNT 588cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn}; 589cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn 5908e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackbornstatic void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray out) 5918e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn{ 5928e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn char buffer[1024]; 5938e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn int numFound = 0; 5948e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 5958e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (out == NULL) { 5968e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn jniThrowNullPointerException(env, "out == null"); 5978e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn return; 5988e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 5998e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 6008e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn int fd = open("/proc/meminfo", O_RDONLY); 6018e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 6028e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (fd < 0) { 603cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn ALOGW("Unable to open /proc/meminfo: %s\n", strerror(errno)); 6048e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn return; 6058e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6068e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 607cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn int len = read(fd, buffer, sizeof(buffer)-1); 6088e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn close(fd); 6098e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 6108e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (len < 0) { 611cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn ALOGW("Empty /proc/meminfo"); 6128e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn return; 6138e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6148e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn buffer[len] = 0; 6158e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 6168e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn static const char* const tags[] = { 6178e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "MemTotal:", 6188e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "MemFree:", 6198e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "Buffers:", 6208e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "Cached:", 6218e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "Shmem:", 6228e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "Slab:", 623cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn "SwapTotal:", 624cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn "SwapFree:", 625b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn "ZRam:", 626b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn "Mapped:", 627b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn "VmallocUsed:", 628b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn "PageTables:", 629b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn "KernelStack:", 6308e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn NULL 6318e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn }; 6328e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn static const int tagsLen[] = { 6338e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 9, 6348e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 8, 6358e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 8, 6368e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 7, 6378e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 6, 6388e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 5, 639cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn 10, 640cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn 9, 641b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn 5, 642b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn 7, 643b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn 12, 644b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn 11, 645b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn 12, 6468e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 0 6478e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn }; 648b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn long mem[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 6498e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 6508e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn char* p = buffer; 651b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6Dianne Hackborn while (*p && numFound < 13) { 6528e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn int i = 0; 6538e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn while (tags[i]) { 6548e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (strncmp(p, tags[i], tagsLen[i]) == 0) { 6558e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn p += tagsLen[i]; 6568e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn while (*p == ' ') p++; 6578e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn char* num = p; 6588e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn while (*p >= '0' && *p <= '9') p++; 6598e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (*p != 0) { 6608e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn *p = 0; 6618e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn p++; 6628e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6638e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn mem[i] = atoll(num); 6648e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn numFound++; 6658e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn break; 6668e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6678e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn i++; 6688e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6698e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn while (*p && *p != '\n') { 6708e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn p++; 6718e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6728e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (*p) p++; 6738e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6748e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 675cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn fd = open("/sys/block/zram0/mem_used_total", O_RDONLY); 676cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn if (fd >= 0) { 677cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn len = read(fd, buffer, sizeof(buffer)-1); 678cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn close(fd); 679cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn if (len > 0) { 680cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn buffer[len] = 0; 681cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn mem[MEMINFO_ZRAM_TOTAL] = atoll(buffer)/1024; 682cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn } 683cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn } 684cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn 6858e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn int maxNum = env->GetArrayLength(out); 686cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn if (maxNum > MEMINFO_COUNT) { 687cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn maxNum = MEMINFO_COUNT; 688cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn } 6898e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn jlong* outArray = env->GetLongArrayElements(out, 0); 6908e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (outArray != NULL) { 691cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn for (int i=0; i<maxNum; i++) { 6928e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn outArray[i] = mem[i]; 6938e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6948e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6958e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn env->ReleaseLongArrayElements(out, outArray, 0); 696b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn} 697b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint read_binder_stat(const char* stat) 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FILE* fp = fopen(BINDER_STATS, "r"); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fp == NULL) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char line[1024]; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char compare[128]; 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = snprintf(compare, 128, "proc %d", getpid()); 7097c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // loop until we have the block that represents this process 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 713c367d48c55e5a3fa0df14fd62889e4bb6b63cb01Elliott Hughes fclose(fp); 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (strncmp(compare, line, len)); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7187c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers // now that we have this process, read until we find the stat that we are looking for 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = snprintf(compare, 128, " %s: ", stat); 7207c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 723c367d48c55e5a3fa0df14fd62889e4bb6b63cb01Elliott Hughes fclose(fp); 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (strncmp(compare, line, len)); 7277c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we have the line, now increment the line ptr to the value 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* ptr = line + len; 730c367d48c55e5a3fa0df14fd62889e4bb6b63cb01Elliott Hughes jint result = atoi(ptr); 731c367d48c55e5a3fa0df14fd62889e4bb6b63cb01Elliott Hughes fclose(fp); 732c367d48c55e5a3fa0df14fd62889e4bb6b63cb01Elliott Hughes return result; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Debug_getBinderSentTransactions(JNIEnv *env, jobject clazz) 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return read_binder_stat("bcTRANSACTION"); 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_getBinderReceivedTransactions(JNIEnv *env, jobject clazz) 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return read_binder_stat("brTRANSACTION"); 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// these are implemented in android_util_Binder.cpp 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz); 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 75006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 75106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* pulled out of bionic */ 75206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenextern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, 75306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t* infoSize, size_t* totalMemory, size_t* backtraceSize); 75406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenextern "C" void free_malloc_leak_info(uint8_t* info); 75506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define SIZE_FLAG_ZYGOTE_CHILD (1<<31) 75606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define BACKTRACE_SIZE 32 75706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 75806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 75906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * This is a qsort() callback. 76006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 76106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * See dumpNativeHeap() for comments about the data format and sort order. 76206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 76306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic int compareHeapRecords(const void* vrec1, const void* vrec2) 76406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 76506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const size_t* rec1 = (const size_t*) vrec1; 76606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const size_t* rec2 = (const size_t*) vrec2; 76706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size1 = *rec1; 76806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size2 = *rec2; 76906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 77006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (size1 < size2) { 77106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 1; 77206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else if (size1 > size2) { 77306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return -1; 77406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 77506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 77606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* bt1 = (intptr_t*)(rec1 + 2); 77706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* bt2 = (intptr_t*)(rec2 + 2); 77806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t idx = 0; idx < BACKTRACE_SIZE; idx++) { 77906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t addr1 = bt1[idx]; 78006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t addr2 = bt2[idx]; 78106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 == addr2) { 78206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 == 0) 78306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden break; 78406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden continue; 78506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 78606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 < addr2) { 78706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return -1; 78806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else if (addr1 > addr2) { 78906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 1; 79006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 79106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 79206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 79306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 0; 79406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 79506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 79606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 79706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * The get_malloc_leak_info() call returns an array of structs that 79806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * look like this: 79906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 80006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * size_t size 80106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * size_t allocations 80206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * intptr_t backtrace[32] 80306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 80406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * "size" is the size of the allocation, "backtrace" is a fixed-size 80506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * array of function pointers, and "allocations" is the number of 80606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * allocations with the exact same size and backtrace. 80706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 80806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * The entries are sorted by descending total size (i.e. size*allocations) 80906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * then allocation count. For best results with "diff" we'd like to sort 81006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * primarily by individual size then stack trace. Since the entries are 81106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * fixed-size, and we're allowed (by the current implementation) to mangle 81206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * them, we can do this in place. 81306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 81406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic void dumpNativeHeap(FILE* fp) 81506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 81606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden uint8_t* info = NULL; 81706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t overallSize, infoSize, totalMemory, backtraceSize; 81806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 81906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, 82006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden &backtraceSize); 82106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (info == NULL) { 82206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Native heap dump not available. To enable, run these" 82306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden " commands (requires root):\n"); 82406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell setprop libc.debug.malloc 1\n"); 82506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell stop\n"); 82606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell start\n"); 82706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 82806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 82906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden assert(infoSize != 0); 83006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden assert(overallSize % infoSize == 0); 83106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 83206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Android Native Heap Dump v1.0\n\n"); 83306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 83406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t recordCount = overallSize / infoSize; 83506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Total memory: %zu\n", totalMemory); 83606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Allocation records: %zd\n", recordCount); 83706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (backtraceSize != BACKTRACE_SIZE) { 838f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat fprintf(fp, "WARNING: mismatched backtrace sizes (%zu vs. %d)\n", 83906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden backtraceSize, BACKTRACE_SIZE); 84006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 84106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "\n"); 84206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 84306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* re-sort the entries */ 84406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden qsort(info, recordCount, infoSize, compareHeapRecords); 84506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 84606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* dump the entries to the file */ 84706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const uint8_t* ptr = info; 84806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t idx = 0; idx < recordCount; idx++) { 84906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size = *(size_t*) ptr; 85006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t allocations = *(size_t*) (ptr + sizeof(size_t)); 85106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* backtrace = (intptr_t*) (ptr + sizeof(size_t) * 2); 85206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 85306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "z %d sz %8zu num %4zu bt", 85406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden (size & SIZE_FLAG_ZYGOTE_CHILD) != 0, 85506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size & ~SIZE_FLAG_ZYGOTE_CHILD, 85606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden allocations); 85706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t bt = 0; bt < backtraceSize; bt++) { 85806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (backtrace[bt] == 0) { 85906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden break; 86006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else { 861f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat#ifdef __LP64__ 862853940331ff2be48ed3e63f459845e5e43d0a131Mark Salyzyn fprintf(fp, " %016" PRIxPTR, backtrace[bt]); 863f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat#else 864853940331ff2be48ed3e63f459845e5e43d0a131Mark Salyzyn fprintf(fp, " %08" PRIxPTR, backtrace[bt]); 865f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat#endif 86606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 86706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 86806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "\n"); 86906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 87006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden ptr += infoSize; 87106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 87206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 87306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden free_malloc_leak_info(info); 874393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom 875393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "MAPS\n"); 876393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom const char* maps = "/proc/self/maps"; 877393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom FILE* in = fopen(maps, "r"); 878393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom if (in == NULL) { 879393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "Could not open %s\n", maps); 880393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom return; 881393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom } 882393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom char buf[BUFSIZ]; 883393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom while (size_t n = fread(buf, sizeof(char), BUFSIZ, in)) { 884393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fwrite(buf, sizeof(char), n, fp); 885393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom } 886393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fclose(in); 887393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom 888393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "END\n"); 88906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 89006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 89106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 89206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * Dump the native heap, writing human-readable output to the specified 89306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * file descriptor. 89406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 89506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz, 89606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jobject fileDescriptor) 89706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 89806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fileDescriptor == NULL) { 8997c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jniThrowNullPointerException(env, "fd == null"); 90006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 90106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 90206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden int origFd = jniGetFDFromFileDescriptor(env, fileDescriptor); 90306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (origFd < 0) { 90406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "Invalid file descriptor"); 90506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 90606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 90706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 90806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* dup() the descriptor so we don't close the original with fclose() */ 90906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden int fd = dup(origFd); 91006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fd < 0) { 9118564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("dup(%d) failed: %s\n", origFd, strerror(errno)); 91206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "dup() failed"); 91306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 91406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 91506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 91606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden FILE* fp = fdopen(fd, "w"); 91706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fp == NULL) { 9188564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("fdopen(%d) failed: %s\n", fd, strerror(errno)); 91906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden close(fd); 92006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "fdopen() failed"); 92106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 92206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 92306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 9245baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Native heap dump starting...\n"); 92506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden dumpNativeHeap(fp); 9265baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Native heap dump complete.\n"); 92706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 92806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fclose(fp); 92906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 93006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 93106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 932f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackbornstatic void android_os_Debug_dumpNativeBacktraceToFile(JNIEnv* env, jobject clazz, 933f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn jint pid, jstring fileName) 934f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn{ 935f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (fileName == NULL) { 9367c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jniThrowNullPointerException(env, "file == null"); 937f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn return; 938f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 939f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn const jchar* str = env->GetStringCritical(fileName, 0); 940f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn String8 fileName8; 941f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (str) { 942f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fileName8 = String8(str, env->GetStringLength(fileName)); 943f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn env->ReleaseStringCritical(fileName, str); 944f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 945f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 946f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn int fd = open(fileName8.string(), O_CREAT | O_WRONLY | O_NOFOLLOW, 0666); /* -rw-rw-rw- */ 947f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (fd < 0) { 948f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fprintf(stderr, "Can't open %s: %s\n", fileName8.string(), strerror(errno)); 949f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn return; 950f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 951f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 952f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (lseek(fd, 0, SEEK_END) < 0) { 953f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fprintf(stderr, "lseek: %s\n", strerror(errno)); 954f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } else { 955f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn dump_backtrace_to_file(pid, fd); 956f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 957f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 958f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn close(fd); 959f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn} 960f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration. 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapSize", "()J", 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapSize }, 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapAllocatedSize", "()J", 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapAllocatedSize }, 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapFreeSize", "()J", 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapFreeSize }, 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getMemoryInfo", "(Landroid/os/Debug$MemoryInfo;)V", 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getDirtyPages }, 9743025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)V", 9753025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn (void*) android_os_Debug_getDirtyPagesPid }, 976b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn { "getPss", "()J", 977b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn (void*) android_os_Debug_getPss }, 9781a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn { "getPss", "(I[J[J)J", 979b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn (void*) android_os_Debug_getPssPid }, 9808e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn { "getMemInfo", "([J)V", 9818e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn (void*) android_os_Debug_getMemInfo }, 98206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden { "dumpNativeHeap", "(Ljava/io/FileDescriptor;)V", 98306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden (void*) android_os_Debug_dumpNativeHeap }, 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderSentTransactions", "()I", 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getBinderSentTransactions }, 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderReceivedTransactions", "()I", 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_getBinderReceivedTransactions }, 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderLocalObjectCount", "()I", 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getLocalObjectCount }, 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderProxyObjectCount", "()I", 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getProxyObjectCount }, 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderDeathObjectCount", "()I", 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getDeathObjectCount }, 994f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn { "dumpNativeBacktraceToFile", "(ILjava/lang/String;)V", 995f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn (void*)android_os_Debug_dumpNativeBacktraceToFile }, 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_os_Debug(JNIEnv *env) 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10005b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int err = memtrack_init(); 10015b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (err != 0) { 10025b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski memtrackLoaded = false; 10035b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski ALOGE("failed to load memtrack module: %d", err); 10045b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } else { 10055b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski memtrackLoaded = true; 10065b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 10075b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz = env->FindClass("android/os/Debug$MemoryInfo"); 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10107c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers // Sanity check the number of other statistics expected in Java matches here. 10117c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I"); 10127c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field); 10133c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum jfieldID numDvkStats_field = env->GetStaticFieldID(clazz, "NUM_DVK_STATS", "I"); 10143c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum jint numDvkStats = env->GetStaticIntField(clazz, numDvkStats_field); 10157c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers int expectedNumOtherStats = _NUM_HEAP - _NUM_CORE_HEAP; 10163c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum if ((numOtherStats + numDvkStats) != expectedNumOtherStats) { 10177c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jniThrowExceptionFmt(env, "java/lang/RuntimeException", 10183c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum "android.os.Debug.Meminfo.NUM_OTHER_STATS+android.os.Debug.Meminfo.NUM_DVK_STATS=%d expected %d", 10193c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum numOtherStats+numDvkStats, expectedNumOtherStats); 10207c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers return JNI_ERR; 10217c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers } 10227c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 10237c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers otherStats_field = env->GetFieldID(clazz, "otherStats", "[I"); 10247c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 10250e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=0; i<_NUM_CORE_HEAP; i++) { 10260e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].pss_field = 10270e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].pss_name, "I"); 10283c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stat_fields[i].pssSwappable_field = 10293c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum env->GetFieldID(clazz, stat_field_names[i].pssSwappable_name, "I"); 10300e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].privateDirty_field = 10310e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I"); 10320e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].sharedDirty_field = 10330e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I"); 10343c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stat_fields[i].privateClean_field = 10353c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I"); 10363a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum stat_fields[i].sharedClean_field = 10373a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I"); 10388883ced18ac25199330843964634fdf70647a127Dianne Hackborn stat_fields[i].swappedOut_field = 10398883ced18ac25199330843964634fdf70647a127Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].swappedOut_name, "I"); 10400e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 10410e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods)); 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 104506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden}; // namespace android 1046