1 // Copyright (C) 2014 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #pragma once 15 16 #include "aemu/base/Compiler.h" 17 18 #include "aemu/base/files/PathUtils.h" 19 #include "aemu/base/system/Memory.h" 20 #include "android/utils/debug.h" 21 22 #include <functional> 23 #include <string> 24 #include <string_view> 25 26 namespace android { 27 namespace base { 28 29 class MemoryProfiler { 30 public: 31 using MemoryUsageBytes = int64_t; 32 33 MemoryProfiler() = default; 34 start()35 void start() { 36 mStartResident = queryCurrentResident(); 37 } 38 queryCurrentResident()39 MemoryUsageBytes queryCurrentResident() { 40 auto memUsage = getMemUsage(); 41 return (MemoryUsageBytes)memUsage.resident; 42 } 43 queryStartResident()44 MemoryUsageBytes queryStartResident() { 45 return mStartResident; 46 } 47 48 private: 49 MemoryUsageBytes mStartResident = 0; 50 DISALLOW_COPY_ASSIGN_AND_MOVE(MemoryProfiler); 51 }; 52 53 class ScopedMemoryProfiler { 54 public: 55 using Callback = std::function<void(std::string_view, 56 std::string_view, 57 MemoryProfiler::MemoryUsageBytes, 58 MemoryProfiler::MemoryUsageBytes)>; 59 ScopedMemoryProfiler(std::string_view tag)60 ScopedMemoryProfiler(std::string_view tag) : mProfiler(), mTag(tag) { 61 mProfiler.start(); 62 check("(start)"); 63 } 64 ScopedMemoryProfiler(std::string_view tag,Callback c)65 ScopedMemoryProfiler(std::string_view tag, Callback c) 66 : mProfiler(), mTag(tag), mCallback(c) { 67 mProfiler.start(); 68 check("(start)"); 69 } 70 71 void check(std::string_view stage = "") { 72 int64_t currRes = mProfiler.queryCurrentResident(); 73 mCallback(mTag.c_str(), stage, 74 currRes, currRes - mProfiler.queryStartResident()); 75 } 76 ~ScopedMemoryProfiler()77 ~ScopedMemoryProfiler() { 78 check("(end)"); 79 } 80 81 private: 82 MemoryProfiler mProfiler; 83 std::string mTag; 84 85 Callback mCallback = {[](std::string_view tag, 86 std::string_view stage, 87 MemoryProfiler::MemoryUsageBytes currentResident, 88 MemoryProfiler::MemoryUsageBytes change) { 89 double megabyte = 1024.0 * 1024.0; 90 derror("%s %s: %f mb current. change: %f mb", 91 c_str(tag).get(), c_str(stage).get(), 92 (double)currentResident / megabyte, (double)change / megabyte); 93 }}; 94 95 DISALLOW_COPY_ASSIGN_AND_MOVE(ScopedMemoryProfiler); 96 }; 97 98 } // namespace base 99 } // namespace android 100