Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(profiler): use pss ram instead of rss #35

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
12 changes: 8 additions & 4 deletions packages/android-performance-profiler/cpp-profiler/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <fstream>
#include <thread>
#include <unistd.h>
#include "meminfo.h"
#include "utils.h"

using std::cout;
Expand Down Expand Up @@ -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)
Expand All @@ -56,7 +56,7 @@ long long printPerformanceMeasure(string pid)
log("=START MEASURE=");
printCpuStats(pid);
log(separator);
printMemoryStats(pid);
printMemoryStats();
log(separator);
printATraceLines();
log(separator);
Expand Down Expand Up @@ -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")
{
Expand Down
50 changes: 50 additions & 0 deletions packages/android-performance-profiler/cpp-profiler/src/meminfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "meminfo.h"
#include <array>
#include <iostream>

std::string exec(std::string cmd)
{
std::array<char, 128> 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<std::chrono::milliseconds>(end - start);
std::cout << "MEMINFO EXEC TIME: " << duration.count() << std::endl;
}
}
18 changes: 18 additions & 0 deletions packages/android-performance-profiler/cpp-profiler/src/meminfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef MEMINFO_H
#define MEMINFO_H

#include <string>

/**
* 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 */
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -49,6 +48,8 @@ export const pollPerformanceMeasures = (
)
);

const ram = processRamOutput(ramStr);

dataCallback({
cpu: cpuMeasures,
fps,
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
});
Original file line number Diff line number Diff line change
@@ -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;
};