diff --git a/packages/android-performance-profiler/cpp-profiler/CMakeLists.txt b/packages/android-performance-profiler/cpp-profiler/CMakeLists.txt index 7ec10557..06be4d97 100644 --- a/packages/android-performance-profiler/cpp-profiler/CMakeLists.txt +++ b/packages/android-performance-profiler/cpp-profiler/CMakeLists.txt @@ -2,4 +2,4 @@ project(android-cmake-helloworld) cmake_minimum_required(VERSION 3.16.0) -add_executable(BAMPerfProfiler src/main.cpp src/atrace.cpp src/utils.cpp) +add_executable(BAMPerfProfiler src/main.cpp src/atrace.cpp src/utils.cpp src/meminfo.cpp) diff --git a/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-arm64-v8a b/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-arm64-v8a index e2325b41..0adbb35f 100755 Binary files a/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-arm64-v8a and b/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-arm64-v8a differ diff --git a/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-armeabi-v7a b/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-armeabi-v7a index a4aac1e5..4e2a3e83 100755 Binary files a/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-armeabi-v7a and b/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-armeabi-v7a differ diff --git a/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-x86 b/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-x86 index dfe63906..81e2ccd1 100755 Binary files a/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-x86 and b/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-x86 differ diff --git a/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-x86_64 b/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-x86_64 index 27a594b5..d545fb84 100755 Binary files a/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-x86_64 and b/packages/android-performance-profiler/cpp-profiler/bin/BAMPerfProfiler-x86_64 differ diff --git a/packages/android-performance-profiler/cpp-profiler/src/main.cpp b/packages/android-performance-profiler/cpp-profiler/src/main.cpp index d9651238..e54200f1 100644 --- a/packages/android-performance-profiler/cpp-profiler/src/main.cpp +++ b/packages/android-performance-profiler/cpp-profiler/src/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "meminfo.h" #include "utils.h" using std::cout; @@ -42,10 +43,9 @@ void printCpuStats(string pid) } } -void printMemoryStats(string pid) +void printMemoryStats() { - string memoryFilePath = "/proc/" + pid + "/statm"; - readFile(memoryFilePath); + log(getCurrentMeminfoResult()); } long long printPerformanceMeasure(string pid) @@ -56,7 +56,7 @@ long long printPerformanceMeasure(string pid) log("=START MEASURE="); printCpuStats(pid); log(separator); - printMemoryStats(pid); + printMemoryStats(); log(separator); printATraceLines(); log(separator); @@ -102,8 +102,12 @@ int main(int argc, char **argv) string pid = argv[2]; std::thread aTraceReadThread(readATraceThread, pid); + std::thread memInfoThread(pollMeminfo, pid); + pollPerformanceMeasures(argv); + aTraceReadThread.join(); + memInfoThread.join(); } else if (methodName == "printPerformanceMeasure") { diff --git a/packages/android-performance-profiler/cpp-profiler/src/meminfo.cpp b/packages/android-performance-profiler/cpp-profiler/src/meminfo.cpp new file mode 100644 index 00000000..ee17b0c8 --- /dev/null +++ b/packages/android-performance-profiler/cpp-profiler/src/meminfo.cpp @@ -0,0 +1,50 @@ +#include "meminfo.h" +#include +#include + +std::string exec(std::string cmd) +{ + std::array buffer; + std::string result; + + auto pipe = popen(cmd.c_str(), "r"); // get rid of shared_ptr + + if (!pipe) + throw std::runtime_error("popen() failed!"); + + while (!feof(pipe)) + { + if (fgets(buffer.data(), 128, pipe) != nullptr) + result += buffer.data(); + } + + auto rc = pclose(pipe); + + if (rc == EXIT_SUCCESS) + { // == 0 + } + else if (rc == EXIT_FAILURE) + { // EXIT_FAILURE is not used by all programs, maybe needs some adaptation. + } + return result; +} + +std::string currentOutput; + +std::string getCurrentMeminfoResult() +{ + return currentOutput; +} + +void pollMeminfo(std::string bundleId) +{ + while (true) + { + + auto start = std::chrono::system_clock::now(); + currentOutput = exec("dumpsys meminfo " + bundleId); + auto end = std::chrono::system_clock::now(); + auto duration = std::chrono::duration_cast(end - start); + std::cout << "MEMINFO EXEC TIME: " << duration.count() << std::endl; + } +} diff --git a/packages/android-performance-profiler/cpp-profiler/src/meminfo.h b/packages/android-performance-profiler/cpp-profiler/src/meminfo.h new file mode 100644 index 00000000..53f80b2b --- /dev/null +++ b/packages/android-performance-profiler/cpp-profiler/src/meminfo.h @@ -0,0 +1,18 @@ +#ifndef MEMINFO_H +#define MEMINFO_H + +#include + +/** + * Serves as in memory buffer for atrace lines + * + * pollMeminfo continually reads from adb shell dumpsys meminfo + * to not pollute the main thread since it takes a long time + * + * it stores current value to be retrievable via + * getCurrentMeminfoResult + */ +std::string getCurrentMeminfoResult(); +void pollMeminfo(std::string bundleId); + +#endif /* MEMINFO_H */ diff --git a/packages/android-performance-profiler/src/commands/pollPerformanceMeasures.ts b/packages/android-performance-profiler/src/commands/pollPerformanceMeasures.ts index 90e08873..37ebc948 100644 --- a/packages/android-performance-profiler/src/commands/pollPerformanceMeasures.ts +++ b/packages/android-performance-profiler/src/commands/pollPerformanceMeasures.ts @@ -21,7 +21,6 @@ export const pollPerformanceMeasures = ( ({ cpu, ram: ramStr, atrace, timestamp, adbExecTime }) => { const subProcessesStats = processOutput(cpu, pid); - const ram = processRamOutput(ramStr); const { frameTimes, interval: atraceInterval } = frameTimeParser.getFrameTimes(atrace, pid); @@ -49,6 +48,8 @@ export const pollPerformanceMeasures = ( ) ); + const ram = processRamOutput(ramStr); + dataCallback({ cpu: cpuMeasures, fps, diff --git a/packages/android-performance-profiler/src/commands/ram/__tests__/pollRamUsage.test.ts b/packages/android-performance-profiler/src/commands/ram/__tests__/pollRamUsage.test.ts new file mode 100644 index 00000000..a467adad --- /dev/null +++ b/packages/android-performance-profiler/src/commands/ram/__tests__/pollRamUsage.test.ts @@ -0,0 +1,57 @@ +import { processOutput } from "../pollRamUsage"; + +const SAMPLE_OUTPUT = `Applications Memory Usage (in Kilobytes): +Uptime: 7096575 Realtime: 8873759 + +** MEMINFO in pid 17749 [com.example] ** + Pss Private Private SwapPss Heap Heap Heap + Total Dirty Clean Dirty Size Alloc Free + ------ ------ ------ ------ ------ ------ ------ + Native Heap 8517 8448 0 28 14848 10681 4166 + Dalvik Heap 2337 1652 616 11 4259 2130 2129 + Dalvik Other 2512 2512 0 0 + Stack 544 544 0 0 + Ashmem 2 0 0 0 + Other dev 16 0 16 0 + .so mmap 11080 920 8672 18 + .apk mmap 2524 248 84 0 + .ttf mmap 97 0 60 0 + .dex mmap 9592 8 7160 0 + .oat mmap 57 0 20 0 + .art mmap 6265 5116 696 0 + Other mmap 95 4 16 0 + EGL mtrack 10824 10824 0 0 + Unknown 23402 23400 0 1 + TOTAL 77922 53676 17340 58 19107 12811 6295 + + App Summary + Pss(KB) + ------ + Java Heap: 7464 + Native Heap: 8448 + Code: 17172 + Stack: 544 + Graphics: 10824 + Private Other: 26564 + System: 6906 + + TOTAL: 77922 TOTAL SWAP PSS: 58 + + Objects + Views: 58 ViewRootImpl: 1 + AppContexts: 5 Activities: 1 + Assets: 5 AssetManagers: 0 + Local Binders: 10 Proxy Binders: 31 + Parcel memory: 5 Parcel count: 23 + Death Recipients: 0 OpenSSL Sockets: 0 + WebViews: 0 + + SQL + MEMORY_USED: 0 + PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0 + +`; + +test("processRamOutput", () => { + expect(processOutput(SAMPLE_OUTPUT)).toEqual(77.922); +}); diff --git a/packages/android-performance-profiler/src/commands/ram/pollRamUsage.ts b/packages/android-performance-profiler/src/commands/ram/pollRamUsage.ts index 6fd6b998..1fe9b91c 100644 --- a/packages/android-performance-profiler/src/commands/ram/pollRamUsage.ts +++ b/packages/android-performance-profiler/src/commands/ram/pollRamUsage.ts @@ -1,10 +1,14 @@ -import { getRAMPageSize } from "../cppProfiler"; +import { Logger } from "@perf-profiler/logger"; -const BYTES_PER_MB = 1024 * 1024; -const RAM_PAGE_SIZE = getRAMPageSize(); +export const processOutput = (result: string) => { + const regexMatch = result.match(/TOTAL( )+(\d+)/); -export const getCommand = (pid: string) => `cat /proc/${pid}/statm`; + if (!regexMatch) { + Logger.error( + `Defaulting to 0MB RAM since output of meminfo couldn't be parsed: ${result}` + ); + return 0; + } -export const processOutput = (result: string) => { - return (parseInt(result.split(" ")[1], 10) * RAM_PAGE_SIZE) / BYTES_PER_MB; + return parseInt(regexMatch[2]) / 1000; };