• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
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  */
15 
16 #include "base/memory/memory_monitor.h"
17 
18 #include <map>
19 #include <mutex>
20 
21 #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM) and !defined(IOS_PLATFORM) and !defined(LINUX_PLATFORM)
22 #include <malloc.h>
23 #endif
24 
25 #include "base/log/dump_log.h"
26 #include "base/log/log.h"
27 
28 namespace OHOS::Ace {
29 
PurgeMallocCache()30 void PurgeMallocCache()
31 {
32 #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM) and !defined(IOS_PLATFORM) and !defined(LINUX_PLATFORM)
33 #if defined(__BIONIC__)
34     mallopt(M_PURGE, 0);
35 #endif
36 #endif
37 }
38 
39 #ifdef ACE_MEMORY_MONITOR
40 class MemoryMonitorImpl : public MemoryMonitor {
41 public:
Add(void * ptr)42     void Add(void* ptr) final
43     {
44         std::lock_guard<std::mutex> lock(mutex_);
45         auto result = memoryMap_.emplace(ptr, MemInfo());
46         if (!result.second) {
47             LOGE("Address is already in memory map");
48             return;
49         }
50 
51         count_++;
52     }
53 
Remove(void * ptr)54     void Remove(void* ptr) final
55     {
56         std::lock_guard<std::mutex> lock(mutex_);
57         auto it = memoryMap_.find(ptr);
58         if (it == memoryMap_.end()) {
59             LOGE("Address MUST be in memory map");
60             return;
61         }
62         count_--;
63 
64         if (it->second.size > 0) {
65             total_ -= it->second.size;
66             auto& info = typeMap_[it->second.typeName];
67             info.count--;
68             info.total -= it->second.size;
69         }
70         memoryMap_.erase(it);
71     }
72 
Update(void * ptr,size_t size,const std::string & typeName)73     void Update(void* ptr, size_t size, const std::string& typeName) final
74     {
75         std::lock_guard<std::mutex> lock(mutex_);
76         auto it = memoryMap_.find(ptr);
77         if (it == memoryMap_.end()) {
78             LOGE("Address MUST be in memory map");
79             return;
80         }
81 
82         it->second.size = size;
83         it->second.typeName = typeName;
84 
85         total_ += size;
86         auto& info = typeMap_[typeName];
87         info.count++;
88         info.total += size;
89     }
90 
Dump() const91     void Dump() const final
92     {
93         std::lock_guard<std::mutex> lock(mutex_);
94         std::string out = "total = " + std::to_string(total_) + ", count = " + std::to_string(count_);
95         DumpLog::GetInstance().Print(0, out);
96         for (auto&& [typeName, info] : typeMap_) {
97             if (info.total == 0) {
98                 continue;
99             }
100             out = typeName + ": total = " + std::to_string(info.total) + ", count = " + std::to_string(info.count);
101             DumpLog::GetInstance().Print(1, out);
102         }
103     }
104 
105 private:
106     struct MemInfo {
107         size_t size = 0;
108         std::string typeName = "Unknown";
109     };
110 
111     struct TypeInfo {
112         size_t count = 0;
113         size_t total = 0;
114     };
115 
116     std::map<void*, MemInfo> memoryMap_;
117     std::map<std::string, TypeInfo> typeMap_;
118     size_t total_ = 0;
119     size_t count_ = 0;
120 
121     mutable std::mutex mutex_;
122 };
123 
GetInstance()124 MemoryMonitor& MemoryMonitor::GetInstance()
125 {
126     static MemoryMonitorImpl instance;
127     return instance;
128 }
129 #endif // ACE_MEMORY_MONITOR
130 
131 } // namespace OHOS::Ace
132