diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index a990b5c1bd30..825fa42d493a 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -337,6 +337,17 @@ namespace api { namespace { +class AppIdProcessIterator : public base::ProcessIterator { + public: + AppIdProcessIterator() : base::ProcessIterator(nullptr) {} + + protected: + bool IncludeEntry() override { + return (entry().parent_pid() == base::GetCurrentProcId() || + entry().pid() == base::GetCurrentProcId()); + } +}; + IconLoader::IconSize GetIconSizeByString(const std::string& size) { if (size == "small") { return IconLoader::IconSize::SMALL; @@ -913,35 +924,38 @@ void App::GetFileIcon(const base::FilePath& path, } v8::Local App::GetAppMemoryInfo(v8::Isolate* isolate) { - AppIdProcessIterator processIterator; - auto processEntry = processIterator.NextProcessEntry(); - mate::Dictionary result = mate::Dictionary::CreateEmpty(isolate); + AppIdProcessIterator process_iterator; + auto processEntry = process_iterator.NextProcessEntry(); + std::vector result; - while(processEntry != nullptr) { + while (processEntry != nullptr) { int64_t pid = processEntry->pid(); auto process = base::Process::OpenWithExtraPrivileges(pid); std::unique_ptr metrics( base::ProcessMetrics::CreateProcessMetrics(process.Handle())); - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - - dict.Set("workingSetSize", + mate::Dictionary pidDict = mate::Dictionary::CreateEmpty(isolate); + mate::Dictionary memoryDict = mate::Dictionary::CreateEmpty(isolate); + + memoryDict.Set("workingSetSize", static_cast(metrics->GetWorkingSetSize() >> 10)); - dict.Set("peakWorkingSetSize", + memoryDict.Set("peakWorkingSetSize", static_cast(metrics->GetPeakWorkingSetSize() >> 10)); size_t private_bytes, shared_bytes; if (metrics->GetMemoryBytes(&private_bytes, &shared_bytes)) { - dict.Set("privateBytes", static_cast(private_bytes >> 10)); - dict.Set("sharedBytes", static_cast(shared_bytes >> 10)); + memoryDict.Set("privateBytes", static_cast(private_bytes >> 10)); + memoryDict.Set("sharedBytes", static_cast(shared_bytes >> 10)); } - result.Set(std::to_string(pid).c_str(), dict); - processEntry = processIterator.NextProcessEntry(); + pidDict.Set("memory", memoryDict); + pidDict.Set("pid", std::to_string(pid)); + result.push_back(pidDict); + processEntry = process_iterator.NextProcessEntry(); } - return result.GetHandle(); + return mate::ConvertToV8(isolate, result); } // static diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 9c35d91af720..240c3b200691 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -166,17 +166,6 @@ class App : public AtomBrowserClient::Delegate, DISALLOW_COPY_AND_ASSIGN(App); }; -class AppIdProcessIterator : public base::ProcessIterator { - public: - AppIdProcessIterator() : base::ProcessIterator(NULL) {} - - protected: - bool IncludeEntry() override { - return (entry().parent_pid() == base::GetCurrentProcId() || - entry().pid() == base::GetCurrentProcId()); - } -}; - } // namespace api } // namespace atom diff --git a/docs/api/app.md b/docs/api/app.md index facc18ec389e..cf537474af24 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -762,20 +762,7 @@ This method can only be called before app is ready. ### `app.getAppMemoryInfo()` -Returns `Object[]`: - -* `pid` Integer - The process id for which memory info is collected for - * `workingSetSize` Integer - The amount of memory currently pinned to actual physical - RAM. - * `peakWorkingSetSize` Integer - The maximum amount of memory that has ever been pinned - to actual physical RAM. - * `privateBytes` Integer - The amount of memory not shared by other processes, such as - JS heap or HTML content. - * `sharedBytes` Integer - The amount of memory shared between processes, typically - memory consumed by the Electron code itself - -Returns an object giving memory usage statistics about all the processes associated with -the app. Note that all statistics are reported in Kilobytes. +Returns [ProcessMemoryInfo[]](structures/process-memory-info.md): Array of `ProcessMemoryInfo` objects that correspond to memory usage statistics of all the processes associated with the app. ### `app.setBadgeCount(count)` _Linux_ _macOS_ diff --git a/docs/api/structures/memory-info.md b/docs/api/structures/memory-info.md new file mode 100644 index 000000000000..69c67f16cc82 --- /dev/null +++ b/docs/api/structures/memory-info.md @@ -0,0 +1,12 @@ +# MemoryInfo Object + +* `workingSetSize` Integer - Process id of the process. +* `workingSetSize` Integer - The amount of memory currently pinned to actual physical RAM. +* `peakWorkingSetSize` Integer - The maximum amount of memory that has ever been pinned + to actual physical RAM. +* `privateBytes` Integer - The amount of memory not shared by other processes, such as + JS heap or HTML content. +* `sharedBytes` Integer - The amount of memory shared between processes, typically + memory consumed by the Electron code itself + +Note that all statistics are reported in Kilobytes. \ No newline at end of file diff --git a/docs/api/structures/process-memory-info.md b/docs/api/structures/process-memory-info.md new file mode 100644 index 000000000000..5083aaa66394 --- /dev/null +++ b/docs/api/structures/process-memory-info.md @@ -0,0 +1,4 @@ +# ProcessMemoryInfo Object + +* `pid` Integer - Process id of the process. +* `memory` MemoryInfo - Memory information of the process. \ No newline at end of file diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 9a9b4334bceb..e210c2205d02 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -532,5 +532,15 @@ describe('app module', function () { }) }) }) + + describe('getAppMemoryInfo API', function () { + it('returns the process memory of all running electron processes', function () { + const appMemoryInfo = app.getAppMemoryInfo(); + assert.ok(appMemoryInfo.length > 0, 'App memory info object is not > 0') + assert.ok(appMemoryInfo[0].memory.workingSetSize > 0, 'working set size is not > 0') + assert.ok(appMemoryInfo[0].memory.peakWorkingSetSize > 0, 'peak working set size is not > 0') + assert.ok(appMemoryInfo[0].pid > 0, 'pid is not > 0') + }) + }) }) })