• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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