106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci#include "include/RAM.h" 1606f6ba60Sopenharmony_ci#include <sstream> 1706f6ba60Sopenharmony_ci#include <fstream> 1806f6ba60Sopenharmony_ci#include <climits> 1906f6ba60Sopenharmony_ci#include <cstdio> 2006f6ba60Sopenharmony_ci#include <algorithm> 2106f6ba60Sopenharmony_ci#include <iostream> 2206f6ba60Sopenharmony_ci#include <thread> 2306f6ba60Sopenharmony_ci#include <string> 2406f6ba60Sopenharmony_ci#include <regex> 2506f6ba60Sopenharmony_ci#include "include/sp_utils.h" 2606f6ba60Sopenharmony_ci#include "memory_collector.h" 2706f6ba60Sopenharmony_ci#include "collect_result.h" 2806f6ba60Sopenharmony_ci#include "include/startup_delay.h" 2906f6ba60Sopenharmony_ci#include "include/sp_log.h" 3006f6ba60Sopenharmony_ci#include "include/common.h" 3106f6ba60Sopenharmony_ci 3206f6ba60Sopenharmony_ciusing namespace OHOS::HiviewDFX; 3306f6ba60Sopenharmony_ciusing namespace OHOS::HiviewDFX::UCollectUtil; 3406f6ba60Sopenharmony_ciusing namespace OHOS::HiviewDFX::UCollect; 3506f6ba60Sopenharmony_ci 3606f6ba60Sopenharmony_cinamespace OHOS { 3706f6ba60Sopenharmony_cinamespace SmartPerf { 3806f6ba60Sopenharmony_cibool g_flagFirst = false; 3906f6ba60Sopenharmony_cistd::map<std::string, std::string> procRamInfoLast { 4006f6ba60Sopenharmony_ci {"pss", "NA"}, 4106f6ba60Sopenharmony_ci {"gpuPss", "NA"}, 4206f6ba60Sopenharmony_ci {"graphicPss", "NA"}, 4306f6ba60Sopenharmony_ci {"arktsHeapPss", "NA"}, 4406f6ba60Sopenharmony_ci {"nativeHeapPss", "NA"}, 4506f6ba60Sopenharmony_ci {"stackPss", "NA"}, 4606f6ba60Sopenharmony_ci {"sharedClean", "NA"}, 4706f6ba60Sopenharmony_ci {"sharedDirty", "NA"}, 4806f6ba60Sopenharmony_ci {"privateClean", "NA"}, 4906f6ba60Sopenharmony_ci {"privateDirty", "NA"}, 5006f6ba60Sopenharmony_ci {"swap", "NA"}, 5106f6ba60Sopenharmony_ci {"swapPss", "NA"}, 5206f6ba60Sopenharmony_ci {"heapSize", "NA"}, 5306f6ba60Sopenharmony_ci {"heapAlloc", "NA"}, 5406f6ba60Sopenharmony_ci {"heapFree", "NA"}, 5506f6ba60Sopenharmony_ci}; 5606f6ba60Sopenharmony_cistd::map<std::string, std::string> RAM::ItemData() 5706f6ba60Sopenharmony_ci{ 5806f6ba60Sopenharmony_ci std::map<std::string, std::string> result; 5906f6ba60Sopenharmony_ci std::map<std::string, std::string> sysRamInfo = RAM::GetSysRamInfo(); 6006f6ba60Sopenharmony_ci for (auto it = sysRamInfo.begin(); it != sysRamInfo.end(); ++it) { 6106f6ba60Sopenharmony_ci result.insert(*it); 6206f6ba60Sopenharmony_ci } 6306f6ba60Sopenharmony_ci if (!processId.empty()) { 6406f6ba60Sopenharmony_ci if (g_flagFirst) { 6506f6ba60Sopenharmony_ci RAM::TriggerGetPss(); 6606f6ba60Sopenharmony_ci } else { 6706f6ba60Sopenharmony_ci procRamInfoLast = RAM::GetRamInfo(); 6806f6ba60Sopenharmony_ci g_flagFirst = true; 6906f6ba60Sopenharmony_ci } 7006f6ba60Sopenharmony_ci for (auto it = procRamInfoLast.begin(); it != procRamInfoLast.end(); ++it) { 7106f6ba60Sopenharmony_ci result.insert(*it); 7206f6ba60Sopenharmony_ci } 7306f6ba60Sopenharmony_ci } else if (!packageName.empty() && processId.empty()) { 7406f6ba60Sopenharmony_ci std::map<std::string, std::string> procMemInfo = RAM::ProcMemNaInfo(); 7506f6ba60Sopenharmony_ci for (auto it = procMemInfo.begin(); it != procMemInfo.end(); ++it) { 7606f6ba60Sopenharmony_ci result.insert(*it); 7706f6ba60Sopenharmony_ci } 7806f6ba60Sopenharmony_ci } 7906f6ba60Sopenharmony_ci LOGI("RAM::ItemData map size(%u)", result.size()); 8006f6ba60Sopenharmony_ci return result; 8106f6ba60Sopenharmony_ci} 8206f6ba60Sopenharmony_ci 8306f6ba60Sopenharmony_civoid RAM::ThreadGetPss() const 8406f6ba60Sopenharmony_ci{ 8506f6ba60Sopenharmony_ci std::map<std::string, std::string> procRamInfo = RAM::GetRamInfo(); 8606f6ba60Sopenharmony_ci procRamInfoLast = procRamInfo; 8706f6ba60Sopenharmony_ci} 8806f6ba60Sopenharmony_ci 8906f6ba60Sopenharmony_civoid RAM::TriggerGetPss() const 9006f6ba60Sopenharmony_ci{ 9106f6ba60Sopenharmony_ci auto tStart = std::thread([this]() { 9206f6ba60Sopenharmony_ci this->ThreadGetPss(); 9306f6ba60Sopenharmony_ci }); 9406f6ba60Sopenharmony_ci tStart.detach(); 9506f6ba60Sopenharmony_ci} 9606f6ba60Sopenharmony_ci 9706f6ba60Sopenharmony_civoid RAM::SetFirstFlag() 9806f6ba60Sopenharmony_ci{ 9906f6ba60Sopenharmony_ci g_flagFirst = false; 10006f6ba60Sopenharmony_ci} 10106f6ba60Sopenharmony_ci 10206f6ba60Sopenharmony_cistd::map<std::string, std::string> RAM::ProcMemNaInfo() const 10306f6ba60Sopenharmony_ci{ 10406f6ba60Sopenharmony_ci std::map<std::string, std::string> procMemInfo; 10506f6ba60Sopenharmony_ci procMemInfo["arktsHeapPss"] = "NA"; 10606f6ba60Sopenharmony_ci procMemInfo["gpuPss"] = "NA"; 10706f6ba60Sopenharmony_ci procMemInfo["graphicPss"] = "NA"; 10806f6ba60Sopenharmony_ci procMemInfo["heapAlloc"] = "NA"; 10906f6ba60Sopenharmony_ci procMemInfo["heapFree"] = "NA"; 11006f6ba60Sopenharmony_ci procMemInfo["heapSize"] = "NA"; 11106f6ba60Sopenharmony_ci procMemInfo["nativeHeapPss"] = "NA"; 11206f6ba60Sopenharmony_ci procMemInfo["privateClean"] = "NA"; 11306f6ba60Sopenharmony_ci procMemInfo["privateDirty"] = "NA"; 11406f6ba60Sopenharmony_ci procMemInfo["pss"] = "NA"; 11506f6ba60Sopenharmony_ci procMemInfo["sharedClean"] = "NA"; 11606f6ba60Sopenharmony_ci procMemInfo["sharedDirty"] = "NA"; 11706f6ba60Sopenharmony_ci procMemInfo["stackPss"] = "NA"; 11806f6ba60Sopenharmony_ci procMemInfo["swap"] = "NA"; 11906f6ba60Sopenharmony_ci procMemInfo["swapPss"] = "NA"; 12006f6ba60Sopenharmony_ci return procMemInfo; 12106f6ba60Sopenharmony_ci} 12206f6ba60Sopenharmony_ci 12306f6ba60Sopenharmony_cistd::map<std::string, std::string> RAM::GetSysRamInfo() const 12406f6ba60Sopenharmony_ci{ 12506f6ba60Sopenharmony_ci std::map<std::string, std::string> sysRamInfo; 12606f6ba60Sopenharmony_ci std::shared_ptr<MemoryCollector> collector = MemoryCollector::Create(); 12706f6ba60Sopenharmony_ci if (collector == nullptr) { 12806f6ba60Sopenharmony_ci LOGE("RAM::GetSysRamInfo collector is nullptr!"); 12906f6ba60Sopenharmony_ci return sysRamInfo; 13006f6ba60Sopenharmony_ci } 13106f6ba60Sopenharmony_ci CollectResult<SysMemory> result = collector->CollectSysMemory(); 13206f6ba60Sopenharmony_ci sysRamInfo["memTotal"] = std::to_string(result.data.memTotal); 13306f6ba60Sopenharmony_ci sysRamInfo["memFree"] = std::to_string(result.data.memFree); 13406f6ba60Sopenharmony_ci sysRamInfo["memAvailable"] = std::to_string(result.data.memAvailable); 13506f6ba60Sopenharmony_ci return sysRamInfo; 13606f6ba60Sopenharmony_ci} 13706f6ba60Sopenharmony_ci 13806f6ba60Sopenharmony_civoid RAM::SetPackageName(const std::string &pName) 13906f6ba60Sopenharmony_ci{ 14006f6ba60Sopenharmony_ci packageName = pName; 14106f6ba60Sopenharmony_ci} 14206f6ba60Sopenharmony_ci 14306f6ba60Sopenharmony_civoid RAM::SetProcessId(const std::string &pid) 14406f6ba60Sopenharmony_ci{ 14506f6ba60Sopenharmony_ci processId = pid; 14606f6ba60Sopenharmony_ci} 14706f6ba60Sopenharmony_ci 14806f6ba60Sopenharmony_cistd::map<std::string, std::string> RAM::GetRamInfo() const 14906f6ba60Sopenharmony_ci{ 15006f6ba60Sopenharmony_ci std::map<std::string, std::string> procRamInfo; 15106f6ba60Sopenharmony_ci std::string pssValue = ""; 15206f6ba60Sopenharmony_ci std::string cmd = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_MEM) + processId; 15306f6ba60Sopenharmony_ci FILE *fd = popen(cmd.c_str(), "r"); 15406f6ba60Sopenharmony_ci if (fd == nullptr) { 15506f6ba60Sopenharmony_ci return procRamInfo; 15606f6ba60Sopenharmony_ci } 15706f6ba60Sopenharmony_ci std::vector<std::string> paramsInfo; 15806f6ba60Sopenharmony_ci procRamInfo = GetPssRamInfo(fd, paramsInfo); 15906f6ba60Sopenharmony_ci for (const auto& value : paramsInfo) { 16006f6ba60Sopenharmony_ci if (procRamInfo[value].empty()) { 16106f6ba60Sopenharmony_ci procRamInfo[value] = "0"; 16206f6ba60Sopenharmony_ci } 16306f6ba60Sopenharmony_ci } 16406f6ba60Sopenharmony_ci return procRamInfo; 16506f6ba60Sopenharmony_ci} 16606f6ba60Sopenharmony_ci 16706f6ba60Sopenharmony_cistd::map<std::string, std::string> RAM::GetPssRamInfo(FILE *fd, std::vector<std::string> paramsInfo) const 16806f6ba60Sopenharmony_ci{ 16906f6ba60Sopenharmony_ci std::map<std::string, std::string> pssRamInfo = ParsePssValues(fd, paramsInfo); 17006f6ba60Sopenharmony_ci std::map<std::string, std::string> sumRamInfo = SaveSumRamInfo(paramsInfo); 17106f6ba60Sopenharmony_ci pssRamInfo.insert(sumRamInfo.cbegin(), sumRamInfo.cend()); 17206f6ba60Sopenharmony_ci if (paramsInfo.empty()) { 17306f6ba60Sopenharmony_ci for (auto &pss : pssRamInfo) { 17406f6ba60Sopenharmony_ci pss.second = "0"; 17506f6ba60Sopenharmony_ci } 17606f6ba60Sopenharmony_ci return pssRamInfo; 17706f6ba60Sopenharmony_ci } 17806f6ba60Sopenharmony_ci return pssRamInfo; 17906f6ba60Sopenharmony_ci} 18006f6ba60Sopenharmony_ci 18106f6ba60Sopenharmony_cistd::map<std::string, std::string> RAM::ParsePssValues(FILE *fd, std::vector<std::string> ¶msInfo) const 18206f6ba60Sopenharmony_ci{ 18306f6ba60Sopenharmony_ci std::map<std::string, std::string> pssRamInfo; 18406f6ba60Sopenharmony_ci std::string gpuPssValue = "0"; 18506f6ba60Sopenharmony_ci std::string graphicPssValue = "0"; 18606f6ba60Sopenharmony_ci std::string arktsHeapPssValue = "0"; 18706f6ba60Sopenharmony_ci std::string nativeHeapPssValue = "0"; 18806f6ba60Sopenharmony_ci std::string stackPssValue = "0"; 18906f6ba60Sopenharmony_ci const int paramEleven = 11; 19006f6ba60Sopenharmony_ci char buf[1024] = {'\0'}; 19106f6ba60Sopenharmony_ci while ((fgets(buf, sizeof(buf), fd)) != nullptr) { 19206f6ba60Sopenharmony_ci std::string line = buf; 19306f6ba60Sopenharmony_ci if (line[0] == '-') { 19406f6ba60Sopenharmony_ci continue; 19506f6ba60Sopenharmony_ci } 19606f6ba60Sopenharmony_ci std::vector<std::string> params; 19706f6ba60Sopenharmony_ci SPUtils::StrSplit(line, " ", params); 19806f6ba60Sopenharmony_ci if (params.size() == paramEleven && params[0].find("GL") != std::string::npos) { 19906f6ba60Sopenharmony_ci gpuPssValue = params[1]; 20006f6ba60Sopenharmony_ci } 20106f6ba60Sopenharmony_ci if (params.size() == paramEleven && params[0].find("Graph") != std::string::npos) { 20206f6ba60Sopenharmony_ci graphicPssValue = params[1]; 20306f6ba60Sopenharmony_ci } 20406f6ba60Sopenharmony_ci if (params[0].find("ark") != std::string::npos) { 20506f6ba60Sopenharmony_ci arktsHeapPssValue = params[RAM_THIRD]; 20606f6ba60Sopenharmony_ci } 20706f6ba60Sopenharmony_ci if (params[0].find("native") != std::string::npos && params[1].find("heap") != std::string::npos) { 20806f6ba60Sopenharmony_ci nativeHeapPssValue = params[RAM_SECOND]; 20906f6ba60Sopenharmony_ci } 21006f6ba60Sopenharmony_ci if (params.size() == paramEleven && params[0].find("stack") != std::string::npos) { 21106f6ba60Sopenharmony_ci stackPssValue = params[1]; 21206f6ba60Sopenharmony_ci } 21306f6ba60Sopenharmony_ci if (params.size() == paramEleven && params[0].find("Total") != std::string::npos) { 21406f6ba60Sopenharmony_ci paramsInfo = params; 21506f6ba60Sopenharmony_ci } 21606f6ba60Sopenharmony_ci if (paramsInfo.size() > 0) { 21706f6ba60Sopenharmony_ci break; 21806f6ba60Sopenharmony_ci } 21906f6ba60Sopenharmony_ci } 22006f6ba60Sopenharmony_ci pclose(fd); 22106f6ba60Sopenharmony_ci pssRamInfo["gpuPss"] = gpuPssValue; 22206f6ba60Sopenharmony_ci pssRamInfo["graphicPss"] = graphicPssValue; 22306f6ba60Sopenharmony_ci pssRamInfo["arktsHeapPss"] = arktsHeapPssValue; 22406f6ba60Sopenharmony_ci pssRamInfo["nativeHeapPss"] = nativeHeapPssValue; 22506f6ba60Sopenharmony_ci pssRamInfo["stackPss"] = stackPssValue; 22606f6ba60Sopenharmony_ci return pssRamInfo; 22706f6ba60Sopenharmony_ci} 22806f6ba60Sopenharmony_ci 22906f6ba60Sopenharmony_cistd::map<std::string, std::string> RAM::SaveSumRamInfo(std::vector<std::string> paramsInfo) const 23006f6ba60Sopenharmony_ci{ 23106f6ba60Sopenharmony_ci std::map<std::string, std::string> sumRamInfo; 23206f6ba60Sopenharmony_ci if (paramsInfo.empty()) { 23306f6ba60Sopenharmony_ci sumRamInfo = ProcMemNaInfo(); 23406f6ba60Sopenharmony_ci for (auto &sumRam : sumRamInfo) { 23506f6ba60Sopenharmony_ci sumRam.second = "0"; 23606f6ba60Sopenharmony_ci } 23706f6ba60Sopenharmony_ci return sumRamInfo; 23806f6ba60Sopenharmony_ci } 23906f6ba60Sopenharmony_ci sumRamInfo["pss"] = paramsInfo[RAM_ONE]; 24006f6ba60Sopenharmony_ci sumRamInfo["sharedClean"] = paramsInfo[RAM_SECOND]; 24106f6ba60Sopenharmony_ci sumRamInfo["sharedDirty"] = paramsInfo[RAM_THIRD]; 24206f6ba60Sopenharmony_ci sumRamInfo["privateClean"] = paramsInfo[RAM_FOURTH]; 24306f6ba60Sopenharmony_ci sumRamInfo["privateDirty"] = paramsInfo[RAM_FIFTH]; 24406f6ba60Sopenharmony_ci sumRamInfo["swap"] = paramsInfo[RAM_SIXTH]; 24506f6ba60Sopenharmony_ci sumRamInfo["swapPss"] = paramsInfo[RAM_SEVENTH]; 24606f6ba60Sopenharmony_ci sumRamInfo["heapSize"] = paramsInfo[RAM_EIGHTH]; 24706f6ba60Sopenharmony_ci sumRamInfo["heapAlloc"] = paramsInfo[RAM_NINTH]; 24806f6ba60Sopenharmony_ci sumRamInfo["heapFree"] = paramsInfo[RAM_TENTH].erase(static_cast<int>(paramsInfo[RAM_TENTH].size()) - 1); 24906f6ba60Sopenharmony_ci return sumRamInfo; 25006f6ba60Sopenharmony_ci} 25106f6ba60Sopenharmony_ci} 25206f6ba60Sopenharmony_ci} 253