Loading core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -274,6 +274,7 @@ cc_library_shared { "libicuuc", "libmedia", "libmediametrics", "libmeminfo", "libaudioclient", "libjpeg", "libusbhost", Loading core/jni/android_os_Debug.cpp +23 −114 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <atomic> #include <iomanip> #include <string> #include <vector> #include <debuggerd/client.h> #include <log/log.h> Loading @@ -41,6 +42,7 @@ #include <nativehelper/JNIHelp.h> #include <nativehelper/ScopedUtfChars.h> #include "jni.h" #include <meminfo/sysmeminfo.h> #include <memtrack/memtrack.h> #include <memunreachable/memunreachable.h> #include "android_os_Debug.h" Loading Loading @@ -712,6 +714,8 @@ static long get_allocated_vmalloc_memory() { return vmalloc_allocated_size; } // The 1:1 mapping of MEMINFO_* enums here must match with the constants from // Debug.java. enum { MEMINFO_TOTAL, MEMINFO_FREE, Loading @@ -731,138 +735,43 @@ enum { MEMINFO_COUNT }; static long long get_zram_mem_used() { #define ZRAM_SYSFS "/sys/block/zram0/" UniqueFile mm_stat_file = MakeUniqueFile(ZRAM_SYSFS "mm_stat", "re"); if (mm_stat_file) { long long mem_used_total = 0; int matched = fscanf(mm_stat_file.get(), "%*d %*d %lld %*d %*d %*d %*d", &mem_used_total); if (matched != 1) ALOGW("failed to parse " ZRAM_SYSFS "mm_stat"); return mem_used_total; } UniqueFile mem_used_total_file = MakeUniqueFile(ZRAM_SYSFS "mem_used_total", "re"); if (mem_used_total_file) { long long mem_used_total = 0; int matched = fscanf(mem_used_total_file.get(), "%lld", &mem_used_total); if (matched != 1) ALOGW("failed to parse " ZRAM_SYSFS "mem_used_total"); return mem_used_total; } return 0; } static void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray out) { char buffer[4096]; size_t numFound = 0; if (out == NULL) { jniThrowNullPointerException(env, "out == null"); return; } int fd = open("/proc/meminfo", O_RDONLY | O_CLOEXEC); if (fd < 0) { ALOGW("Unable to open /proc/meminfo: %s\n", strerror(errno)); int outLen = env->GetArrayLength(out); if (outLen < MEMINFO_COUNT) { jniThrowRuntimeException(env, "outLen < MEMINFO_COUNT"); return; } int len = read(fd, buffer, sizeof(buffer)-1); close(fd); if (len < 0) { ALOGW("Empty /proc/meminfo"); // Read system memory info including ZRAM. The values are stored in the vector // in the same order as MEMINFO_* enum std::vector<uint64_t> mem(MEMINFO_COUNT); std::vector<std::string> tags(::android::meminfo::SysMemInfo::kDefaultSysMemInfoTags); tags.insert(tags.begin() + MEMINFO_ZRAM_TOTAL, "Zram:"); ::android::meminfo::SysMemInfo smi; if (!smi.ReadMemInfo(tags, &mem)) { jniThrowRuntimeException(env, "SysMemInfo read failed"); return; } buffer[len] = 0; static const char* const tags[] = { "MemTotal:", "MemFree:", "Buffers:", "Cached:", "Shmem:", "Slab:", "SReclaimable:", "SUnreclaim:", "SwapTotal:", "SwapFree:", "ZRam:", "Mapped:", "VmallocUsed:", "PageTables:", "KernelStack:", NULL }; static const int tagsLen[] = { 9, 8, 8, 7, 6, 5, 13, 11, 10, 9, 5, 7, 12, 11, 12, 0 }; long mem[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; char* p = buffer; while (*p && numFound < (sizeof(tagsLen) / sizeof(tagsLen[0]))) { int i = 0; while (tags[i]) { if (strncmp(p, tags[i], tagsLen[i]) == 0) { p += tagsLen[i]; while (*p == ' ') p++; char* num = p; while (*p >= '0' && *p <= '9') p++; if (*p != 0) { *p = 0; p++; } mem[i] = atoll(num); numFound++; break; } i++; } while (*p && *p != '\n') { p++; } if (*p) p++; } mem[MEMINFO_ZRAM_TOTAL] = get_zram_mem_used() / 1024; // Recompute Vmalloc Used since the value in meminfo // doesn't account for I/O remapping which doesn't use RAM. mem[MEMINFO_VMALLOC_USED] = get_allocated_vmalloc_memory() / 1024; int maxNum = env->GetArrayLength(out); if (maxNum > MEMINFO_COUNT) { maxNum = MEMINFO_COUNT; } jlong* outArray = env->GetLongArrayElements(out, 0); if (outArray != NULL) { for (int i=0; i<maxNum; i++) { outLen = MEMINFO_COUNT; for (int i = 0; i < outLen; i++) { // TODO: move get_allocated_vmalloc_memory() to libmeminfo if (i == MEMINFO_VMALLOC_USED) { outArray[i] = get_allocated_vmalloc_memory() / 1024; continue; } outArray[i] = mem[i]; } } env->ReleaseLongArrayElements(out, outArray, 0); } Loading core/jni/android_util_Process.cpp +26 −52 Original line number Diff line number Diff line Loading @@ -25,8 +25,12 @@ #include <cutils/sched_policy.h> #include <utils/String8.h> #include <utils/Vector.h> #include <meminfo/sysmeminfo.h> #include <processgroup/processgroup.h> #include <string> #include <vector> #include "core_jni_helpers.h" #include "android_util_Binder.h" Loading @@ -39,9 +43,11 @@ #include <inttypes.h> #include <pwd.h> #include <signal.h> #include <string.h> #include <sys/errno.h> #include <sys/resource.h> #include <sys/stat.h> #include <sys/sysinfo.h> #include <sys/types.h> #include <unistd.h> Loading Loading @@ -603,66 +609,34 @@ static int pid_compare(const void* v1, const void* v2) return *((const jint*)v1) - *((const jint*)v2); } static jlong getFreeMemoryImpl(const char* const sums[], const size_t sumsLen[], size_t num) static jlong android_os_Process_getFreeMemory(JNIEnv* env, jobject clazz) { int fd = open("/proc/meminfo", O_RDONLY | O_CLOEXEC); if (fd < 0) { ALOGW("Unable to open /proc/meminfo"); return -1; } char buffer[2048]; const int len = read(fd, buffer, sizeof(buffer)-1); close(fd); if (len < 0) { ALOGW("Unable to read /proc/meminfo"); return -1; } buffer[len] = 0; size_t numFound = 0; jlong mem = 0; static const std::vector<std::string> memFreeTags = { ::android::meminfo::SysMemInfo::kMemFree, ::android::meminfo::SysMemInfo::kMemCached, }; std::vector<uint64_t> mem(memFreeTags.size()); ::android::meminfo::SysMemInfo smi; char* p = buffer; while (*p && numFound < num) { int i = 0; while (sums[i]) { if (strncmp(p, sums[i], sumsLen[i]) == 0) { p += sumsLen[i]; while (*p == ' ') p++; char* num = p; while (*p >= '0' && *p <= '9') p++; if (*p != 0) { *p = 0; p++; if (*p == 0) p--; } mem += atoll(num) * 1024; numFound++; break; } i++; } p++; if (!smi.ReadMemInfo(memFreeTags, &mem)) { jniThrowRuntimeException(env, "SysMemInfo read failed to get Free Memory"); return -1L; } return numFound > 0 ? mem : -1; jlong sum = 0; std::for_each(mem.begin(), mem.end(), [&](uint64_t val) { sum += val; }); return sum * 1024; } static jlong android_os_Process_getFreeMemory(JNIEnv* env, jobject clazz) static jlong android_os_Process_getTotalMemory(JNIEnv* env, jobject clazz) { static const char* const sums[] = { "MemFree:", "Cached:", NULL }; static const size_t sumsLen[] = { strlen("MemFree:"), strlen("Cached:"), 0 }; return getFreeMemoryImpl(sums, sumsLen, 2); struct sysinfo si; if (sysinfo(&si) == -1) { ALOGE("sysinfo failed: %s", strerror(errno)); return -1; } static jlong android_os_Process_getTotalMemory(JNIEnv* env, jobject clazz) { static const char* const sums[] = { "MemTotal:", NULL }; static const size_t sumsLen[] = { strlen("MemTotal:"), 0 }; return getFreeMemoryImpl(sums, sumsLen, 1); return si.totalram; } void android_os_Process_readProcLines(JNIEnv* env, jobject clazz, jstring fileStr, Loading Loading
core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -274,6 +274,7 @@ cc_library_shared { "libicuuc", "libmedia", "libmediametrics", "libmeminfo", "libaudioclient", "libjpeg", "libusbhost", Loading
core/jni/android_os_Debug.cpp +23 −114 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <atomic> #include <iomanip> #include <string> #include <vector> #include <debuggerd/client.h> #include <log/log.h> Loading @@ -41,6 +42,7 @@ #include <nativehelper/JNIHelp.h> #include <nativehelper/ScopedUtfChars.h> #include "jni.h" #include <meminfo/sysmeminfo.h> #include <memtrack/memtrack.h> #include <memunreachable/memunreachable.h> #include "android_os_Debug.h" Loading Loading @@ -712,6 +714,8 @@ static long get_allocated_vmalloc_memory() { return vmalloc_allocated_size; } // The 1:1 mapping of MEMINFO_* enums here must match with the constants from // Debug.java. enum { MEMINFO_TOTAL, MEMINFO_FREE, Loading @@ -731,138 +735,43 @@ enum { MEMINFO_COUNT }; static long long get_zram_mem_used() { #define ZRAM_SYSFS "/sys/block/zram0/" UniqueFile mm_stat_file = MakeUniqueFile(ZRAM_SYSFS "mm_stat", "re"); if (mm_stat_file) { long long mem_used_total = 0; int matched = fscanf(mm_stat_file.get(), "%*d %*d %lld %*d %*d %*d %*d", &mem_used_total); if (matched != 1) ALOGW("failed to parse " ZRAM_SYSFS "mm_stat"); return mem_used_total; } UniqueFile mem_used_total_file = MakeUniqueFile(ZRAM_SYSFS "mem_used_total", "re"); if (mem_used_total_file) { long long mem_used_total = 0; int matched = fscanf(mem_used_total_file.get(), "%lld", &mem_used_total); if (matched != 1) ALOGW("failed to parse " ZRAM_SYSFS "mem_used_total"); return mem_used_total; } return 0; } static void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray out) { char buffer[4096]; size_t numFound = 0; if (out == NULL) { jniThrowNullPointerException(env, "out == null"); return; } int fd = open("/proc/meminfo", O_RDONLY | O_CLOEXEC); if (fd < 0) { ALOGW("Unable to open /proc/meminfo: %s\n", strerror(errno)); int outLen = env->GetArrayLength(out); if (outLen < MEMINFO_COUNT) { jniThrowRuntimeException(env, "outLen < MEMINFO_COUNT"); return; } int len = read(fd, buffer, sizeof(buffer)-1); close(fd); if (len < 0) { ALOGW("Empty /proc/meminfo"); // Read system memory info including ZRAM. The values are stored in the vector // in the same order as MEMINFO_* enum std::vector<uint64_t> mem(MEMINFO_COUNT); std::vector<std::string> tags(::android::meminfo::SysMemInfo::kDefaultSysMemInfoTags); tags.insert(tags.begin() + MEMINFO_ZRAM_TOTAL, "Zram:"); ::android::meminfo::SysMemInfo smi; if (!smi.ReadMemInfo(tags, &mem)) { jniThrowRuntimeException(env, "SysMemInfo read failed"); return; } buffer[len] = 0; static const char* const tags[] = { "MemTotal:", "MemFree:", "Buffers:", "Cached:", "Shmem:", "Slab:", "SReclaimable:", "SUnreclaim:", "SwapTotal:", "SwapFree:", "ZRam:", "Mapped:", "VmallocUsed:", "PageTables:", "KernelStack:", NULL }; static const int tagsLen[] = { 9, 8, 8, 7, 6, 5, 13, 11, 10, 9, 5, 7, 12, 11, 12, 0 }; long mem[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; char* p = buffer; while (*p && numFound < (sizeof(tagsLen) / sizeof(tagsLen[0]))) { int i = 0; while (tags[i]) { if (strncmp(p, tags[i], tagsLen[i]) == 0) { p += tagsLen[i]; while (*p == ' ') p++; char* num = p; while (*p >= '0' && *p <= '9') p++; if (*p != 0) { *p = 0; p++; } mem[i] = atoll(num); numFound++; break; } i++; } while (*p && *p != '\n') { p++; } if (*p) p++; } mem[MEMINFO_ZRAM_TOTAL] = get_zram_mem_used() / 1024; // Recompute Vmalloc Used since the value in meminfo // doesn't account for I/O remapping which doesn't use RAM. mem[MEMINFO_VMALLOC_USED] = get_allocated_vmalloc_memory() / 1024; int maxNum = env->GetArrayLength(out); if (maxNum > MEMINFO_COUNT) { maxNum = MEMINFO_COUNT; } jlong* outArray = env->GetLongArrayElements(out, 0); if (outArray != NULL) { for (int i=0; i<maxNum; i++) { outLen = MEMINFO_COUNT; for (int i = 0; i < outLen; i++) { // TODO: move get_allocated_vmalloc_memory() to libmeminfo if (i == MEMINFO_VMALLOC_USED) { outArray[i] = get_allocated_vmalloc_memory() / 1024; continue; } outArray[i] = mem[i]; } } env->ReleaseLongArrayElements(out, outArray, 0); } Loading
core/jni/android_util_Process.cpp +26 −52 Original line number Diff line number Diff line Loading @@ -25,8 +25,12 @@ #include <cutils/sched_policy.h> #include <utils/String8.h> #include <utils/Vector.h> #include <meminfo/sysmeminfo.h> #include <processgroup/processgroup.h> #include <string> #include <vector> #include "core_jni_helpers.h" #include "android_util_Binder.h" Loading @@ -39,9 +43,11 @@ #include <inttypes.h> #include <pwd.h> #include <signal.h> #include <string.h> #include <sys/errno.h> #include <sys/resource.h> #include <sys/stat.h> #include <sys/sysinfo.h> #include <sys/types.h> #include <unistd.h> Loading Loading @@ -603,66 +609,34 @@ static int pid_compare(const void* v1, const void* v2) return *((const jint*)v1) - *((const jint*)v2); } static jlong getFreeMemoryImpl(const char* const sums[], const size_t sumsLen[], size_t num) static jlong android_os_Process_getFreeMemory(JNIEnv* env, jobject clazz) { int fd = open("/proc/meminfo", O_RDONLY | O_CLOEXEC); if (fd < 0) { ALOGW("Unable to open /proc/meminfo"); return -1; } char buffer[2048]; const int len = read(fd, buffer, sizeof(buffer)-1); close(fd); if (len < 0) { ALOGW("Unable to read /proc/meminfo"); return -1; } buffer[len] = 0; size_t numFound = 0; jlong mem = 0; static const std::vector<std::string> memFreeTags = { ::android::meminfo::SysMemInfo::kMemFree, ::android::meminfo::SysMemInfo::kMemCached, }; std::vector<uint64_t> mem(memFreeTags.size()); ::android::meminfo::SysMemInfo smi; char* p = buffer; while (*p && numFound < num) { int i = 0; while (sums[i]) { if (strncmp(p, sums[i], sumsLen[i]) == 0) { p += sumsLen[i]; while (*p == ' ') p++; char* num = p; while (*p >= '0' && *p <= '9') p++; if (*p != 0) { *p = 0; p++; if (*p == 0) p--; } mem += atoll(num) * 1024; numFound++; break; } i++; } p++; if (!smi.ReadMemInfo(memFreeTags, &mem)) { jniThrowRuntimeException(env, "SysMemInfo read failed to get Free Memory"); return -1L; } return numFound > 0 ? mem : -1; jlong sum = 0; std::for_each(mem.begin(), mem.end(), [&](uint64_t val) { sum += val; }); return sum * 1024; } static jlong android_os_Process_getFreeMemory(JNIEnv* env, jobject clazz) static jlong android_os_Process_getTotalMemory(JNIEnv* env, jobject clazz) { static const char* const sums[] = { "MemFree:", "Cached:", NULL }; static const size_t sumsLen[] = { strlen("MemFree:"), strlen("Cached:"), 0 }; return getFreeMemoryImpl(sums, sumsLen, 2); struct sysinfo si; if (sysinfo(&si) == -1) { ALOGE("sysinfo failed: %s", strerror(errno)); return -1; } static jlong android_os_Process_getTotalMemory(JNIEnv* env, jobject clazz) { static const char* const sums[] = { "MemTotal:", NULL }; static const size_t sumsLen[] = { strlen("MemTotal:"), 0 }; return getFreeMemoryImpl(sums, sumsLen, 1); return si.totalram; } void android_os_Process_readProcLines(JNIEnv* env, jobject clazz, jstring fileStr, Loading