diff options
author | 2018-12-18 21:49:00 +0000 | |
---|---|---|
committer | 2018-12-18 21:49:00 +0000 | |
commit | 4465267f1de82b88c80a0aafd54b880814a104c8 (patch) | |
tree | 40d7cac04715993144995e34e74b1a06e67c451a | |
parent | f674b60e8dd729039d8cd92690cbcbb27a0789a5 (diff) | |
parent | be825416ec9239504fcbcb785d8173af8fcc3269 (diff) |
Merge "Start using libmeminfo for all memory stats gathering."
-rw-r--r-- | core/jni/Android.bp | 1 | ||||
-rw-r--r-- | core/jni/android_os_Debug.cpp | 137 | ||||
-rw-r--r-- | core/jni/android_util_Process.cpp | 78 |
3 files changed, 50 insertions, 166 deletions
diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 43f8d00bb5f1..21fa75eb35e0 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -274,6 +274,7 @@ cc_library_shared { "libicuuc", "libmedia", "libmediametrics", + "libmeminfo", "libaudioclient", "libjpeg", "libusbhost", diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index fa1da4bfbf3a..888dab19c247 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -32,6 +32,7 @@ #include <atomic> #include <iomanip> #include <string> +#include <vector> #include <debuggerd/client.h> #include <log/log.h> @@ -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" @@ -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, @@ -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); } diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 102a0b7b8957..0c1a8aa18370 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -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" @@ -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> @@ -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); + 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; - if (fd < 0) { - ALOGW("Unable to open /proc/meminfo"); - return -1; + if (!smi.ReadMemInfo(memFreeTags, &mem)) { + jniThrowRuntimeException(env, "SysMemInfo read failed to get Free Memory"); + return -1L; } - 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; - - 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++; - } - - return numFound > 0 ? mem : -1; -} - -static jlong android_os_Process_getFreeMemory(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); + jlong sum = 0; + std::for_each(mem.begin(), mem.end(), [&](uint64_t val) { sum += val; }); + return sum * 1024; } 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); + struct sysinfo si; + if (sysinfo(&si) == -1) { + ALOGE("sysinfo failed: %s", strerror(errno)); + return -1; + } + + return si.totalram; } void android_os_Process_readProcLines(JNIEnv* env, jobject clazz, jstring fileStr, |