Commit d5b5df6a authored by erikchen's avatar erikchen Committed by Commit Bot

[Reland #2] Switch task manager to use the memory_instrumentation interface.

Reland #1 ran into two problems.
  * Timeouts on mac ASAN tests were caused by a mojo bug. See Issue 771805 for
  more details.
  * An incorrectly appearing views scrollbar was caused by a logic bug in
  ScrollView. See Issue 771502 for more details.

CL description from original CL:
> The memory_instrumentation interface on the content_browser service exposes
> cross-platform, consistent memory metrics that should also be used by the task
> manager.
>
> This CL adds a new column to the task manager: Memory Footprint. See
> https://docs.google.com/document/d/1PZyRzChnvkUNUB85Op46aqkFXuAGUJi751DJuB6O40g/edit#
> for more details.
>
> Bug: 756276
> Reviewed-on: https://chromium-review.googlesource.com/646047
> Reviewed-by: Nick Carter <nick@chromium.org>
> Reviewed-by: Primiano Tucci <primiano@chromium.org>
> Commit-Queue: Erik Chen <erikchen@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#506220}

Bug: 756276
TBR: nick@chromium.org
Change-Id: Iffae21fed72410de818180351b66003940f53a3e
Reviewed-on: https://chromium-review.googlesource.com/710172
Commit-Queue: Erik Chen <erikchen@chromium.org>
Reviewed-by: default avatarErik Chen <erikchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#509929}
parent 47981817
......@@ -2929,6 +2929,9 @@ From <ph name="DOWNLOAD_DOMAIN">$3<ex>example.com</ex></ph>
<message name="IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN" desc="Task manager process memory column. This is the similar to the process 'working set' reported by the Windows Task Manager">
Memory
</message>
<message name="IDS_TASK_MANAGER_MEM_FOOTPRINT_COLUMN" desc="Task manager process memory footprint column. This is the amount of memory used by the process.">
Memory footprint
</message>
<message name="IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN" desc="Task manager process private memory column. This is the allocated size that cannot be shared with other processes">
Private memory
</message>
......@@ -3006,6 +3009,9 @@ From <ph name="DOWNLOAD_DOMAIN">$3<ex>example.com</ex></ph>
<message name="IDS_TASK_MANAGER_CPU_TIME_COLUMN" desc="The text of the CPU time column. This is the time that this process actually occupies the CPU.">
CPU Time
</message>
<message name="IDS_TASK_MANAGER_MEM_FOOTPRINT_COLUMN" desc="Task manager process memory footprint column. This is the amount of memory used by the process.">
Memory Footprint
</message>
<message name="IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN" desc="Task manager process memory column. This is the similar to the process 'working set' reported by the Windows Task Manager">
Memory
</message>
......
......@@ -24,7 +24,8 @@ namespace {
// A mask for the refresh types that are done in the background thread.
const int kBackgroundRefreshTypesMask =
REFRESH_TYPE_CPU | REFRESH_TYPE_MEMORY | REFRESH_TYPE_IDLE_WAKEUPS |
REFRESH_TYPE_CPU | REFRESH_TYPE_PHYSICAL_MEMORY |
REFRESH_TYPE_MEMORY_DETAILS | REFRESH_TYPE_IDLE_WAKEUPS |
#if defined(OS_WIN)
REFRESH_TYPE_START_TIME | REFRESH_TYPE_CPU_TIME |
#endif // defined(OS_WIN)
......@@ -89,6 +90,7 @@ TaskGroup::TaskGroup(
expected_on_bg_done_flags_(kBackgroundRefreshTypesMask),
current_on_bg_done_flags_(0),
platform_independent_cpu_usage_(0.0),
memory_footprint_(-1),
gpu_memory_(-1),
memory_state_(base::MemoryState::UNKNOWN),
per_process_network_usage_rate_(-1),
......@@ -327,7 +329,8 @@ void TaskGroup::OnMemoryUsageRefreshDone(MemoryUsageStats memory_usage) {
OnBackgroundRefreshTypeFinished(REFRESH_TYPE_MEMORY_DETAILS);
#else
memory_usage_ = memory_usage;
OnBackgroundRefreshTypeFinished(REFRESH_TYPE_MEMORY);
OnBackgroundRefreshTypeFinished(REFRESH_TYPE_PHYSICAL_MEMORY |
REFRESH_TYPE_MEMORY_DETAILS);
#endif // OS_WIN
}
......
......@@ -74,6 +74,8 @@ class TaskGroup {
}
base::Time start_time() const { return start_time_; }
base::TimeDelta cpu_time() const { return cpu_time_; }
void set_footprint_bytes(int64_t footprint) { memory_footprint_ = footprint; }
int64_t footprint_bytes() const { return memory_footprint_; }
int64_t private_bytes() const { return memory_usage_.private_bytes; }
int64_t shared_bytes() const { return memory_usage_.shared_bytes; }
int64_t physical_bytes() const { return memory_usage_.physical_bytes; }
......@@ -164,6 +166,7 @@ class TaskGroup {
base::Time start_time_; // Only calculated On Windows now.
base::TimeDelta cpu_time_; // Only calculated On Windows now.
MemoryUsageStats memory_usage_;
int64_t memory_footprint_;
int64_t gpu_memory_;
base::MemoryState memory_state_;
// The network usage in bytes per second as the sum of all network usages of
......
......@@ -71,8 +71,8 @@ void TaskGroupSampler::Refresh(int64_t refresh_flags) {
on_cpu_refresh_callback_);
}
if (TaskManagerObserver::IsResourceRefreshEnabled(REFRESH_TYPE_MEMORY,
refresh_flags)) {
if (TaskManagerObserver::IsResourceRefreshEnabled(
REFRESH_TYPE_MEMORY_NON_MEMORY_INSTRUMENTATION, refresh_flags)) {
base::PostTaskAndReplyWithResult(
blocking_pool_runner_.get(),
FROM_HERE,
......
......@@ -27,6 +27,7 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/task_manager/providers/arc/arc_process_task_provider.h"
......@@ -51,6 +52,7 @@ TaskManagerImpl::TaskManagerImpl()
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
shared_sampler_(new SharedSampler(blocking_pool_runner_)),
is_running_(false),
waiting_for_memory_dump_(false),
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
......@@ -118,6 +120,10 @@ base::TimeDelta TaskManagerImpl::GetCpuTime(TaskId task_id) const {
#endif
}
int64_t TaskManagerImpl::GetMemoryFootprintUsage(TaskId task_id) const {
return GetTaskGroupByTaskId(task_id)->footprint_bytes();
}
int64_t TaskManagerImpl::GetPhysicalMemoryUsage(TaskId task_id) const {
return GetTaskGroupByTaskId(task_id)->physical_bytes();
}
......@@ -505,6 +511,21 @@ void TaskManagerImpl::OnVideoMemoryUsageStatsUpdate(
gpu_memory_stats_ = gpu_memory_stats;
}
void TaskManagerImpl::OnReceivedMemoryDump(
bool success,
memory_instrumentation::mojom::GlobalMemoryDumpPtr dump) {
waiting_for_memory_dump_ = false;
if (!success)
return;
for (const memory_instrumentation::mojom::ProcessMemoryDumpPtr& pmd :
dump->process_dumps) {
auto it = task_groups_by_proc_id_.find(pmd->pid);
if (it == task_groups_by_proc_id_.end())
continue;
it->second->set_footprint_bytes(pmd->os_dump->private_footprint_kb * 1024);
}
}
void TaskManagerImpl::Refresh() {
if (IsResourceRefreshEnabled(REFRESH_TYPE_GPU_MEMORY)) {
content::GpuDataManager::GetInstance()->RequestVideoMemoryUsageStatsUpdate(
......@@ -512,6 +533,16 @@ void TaskManagerImpl::Refresh() {
weak_ptr_factory_.GetWeakPtr()));
}
if (IsResourceRefreshEnabled(REFRESH_TYPE_MEMORY_FOOTPRINT) &&
!waiting_for_memory_dump_) {
// The callback keeps this object alive until the callback is invoked.
waiting_for_memory_dump_ = true;
auto callback = base::Bind(&TaskManagerImpl::OnReceivedMemoryDump,
weak_ptr_factory_.GetWeakPtr());
memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDump(std::move(callback));
}
for (auto& groups_itr : task_groups_by_proc_id_) {
groups_itr.second->Refresh(gpu_memory_stats_,
GetCurrentRefreshTime(),
......
......@@ -24,6 +24,7 @@
#include "chrome/browser/task_manager/sampling/task_manager_io_thread_helper.h"
#include "chrome/browser/task_manager/task_manager_interface.h"
#include "gpu/ipc/common/memory_stats.h"
#include "services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom.h"
namespace task_manager {
......@@ -44,6 +45,7 @@ class TaskManagerImpl : public TaskManagerInterface,
double GetPlatformIndependentCPUUsage(TaskId task_id) const override;
base::Time GetStartTime(TaskId task_id) const override;
base::TimeDelta GetCpuTime(TaskId task_id) const override;
int64_t GetMemoryFootprintUsage(TaskId task_id) const override;
int64_t GetPhysicalMemoryUsage(TaskId task_id) const override;
int64_t GetPrivateMemoryUsage(TaskId task_id) const override;
int64_t GetSharedMemoryUsage(TaskId task_id) const override;
......@@ -108,6 +110,9 @@ class TaskManagerImpl : public TaskManagerInterface,
void OnVideoMemoryUsageStatsUpdate(
const gpu::VideoMemoryUsageStats& gpu_memory_stats);
void OnReceivedMemoryDump(
bool success,
memory_instrumentation::mojom::GlobalMemoryDumpPtr ptr);
// task_manager::TaskManagerInterface:
void Refresh() override;
......@@ -170,6 +175,10 @@ class TaskManagerImpl : public TaskManagerInterface,
// running.
bool is_running_;
// This is set to true while waiting for a global memory dump from
// memory_instrumentation.
bool waiting_for_memory_dump_;
base::WeakPtrFactory<TaskManagerImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(TaskManagerImpl);
};
......
......@@ -639,6 +639,9 @@ IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, WebWorkerJSHeapMemory) {
ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerStatToExceed(
MatchTab("title1.html"), ColumnSpecifier::V8_MEMORY_USED,
minimal_heap_size));
ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerStatToExceed(
MatchTab("title1.html"), ColumnSpecifier::MEMORY_FOOTPRINT,
minimal_heap_size));
ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchTab("title1.html")));
}
......@@ -890,9 +893,9 @@ IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, HistoryNavigationInNewTab) {
MatchTab("title1.html"), ColumnSpecifier::PROCESS_ID,
base::kNullProcessId));
ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerStatToExceed(
MatchTab("title1.html"), ColumnSpecifier::PHYSICAL_MEMORY, 1000));
MatchTab("title1.html"), ColumnSpecifier::MEMORY_FOOTPRINT, 1000));
ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerStatToExceed(
MatchTab("About Version"), ColumnSpecifier::PHYSICAL_MEMORY, 1000));
MatchTab("About Version"), ColumnSpecifier::MEMORY_FOOTPRINT, 1000));
}
IN_PROC_BROWSER_TEST_P(TaskManagerOOPIFBrowserTest, SubframeHistoryNavigation) {
......@@ -965,9 +968,9 @@ IN_PROC_BROWSER_TEST_P(TaskManagerOOPIFBrowserTest, SubframeHistoryNavigation) {
// Subframe processes should report some amount of physical memory usage.
ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerStatToExceed(
MatchSubframe("http://d.com/"), ColumnSpecifier::PHYSICAL_MEMORY, 1000));
MatchSubframe("http://d.com/"), ColumnSpecifier::MEMORY_FOOTPRINT, 1000));
ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerStatToExceed(
MatchSubframe("http://e.com/"), ColumnSpecifier::PHYSICAL_MEMORY, 1000));
MatchSubframe("http://e.com/"), ColumnSpecifier::MEMORY_FOOTPRINT, 1000));
}
IN_PROC_BROWSER_TEST_P(TaskManagerOOPIFBrowserTest, KillSubframe) {
......
......@@ -108,6 +108,8 @@ class ResourceChangeObserver {
return "N/A";
case ColumnSpecifier::PROCESS_ID:
return "Process ID";
case ColumnSpecifier::MEMORY_FOOTPRINT:
return "Memory Footprint";
case ColumnSpecifier::PHYSICAL_MEMORY:
return "Physical Memory";
case ColumnSpecifier::V8_MEMORY:
......
......@@ -22,6 +22,7 @@ namespace browsertest_util {
// manager model. Please add more here as needed by tests.
enum class ColumnSpecifier {
PROCESS_ID,
MEMORY_FOOTPRINT,
PHYSICAL_MEMORY,
V8_MEMORY,
V8_MEMORY_USED,
......
......@@ -87,9 +87,10 @@ class TaskManagerInterface {
// Only implemented in Windows now.
virtual base::TimeDelta GetCpuTime(TaskId task_id) const = 0;
// Returns the current physical/private/shared memory usage of the task with
// |task_id| in bytes. A value of -1 means no valid value is currently
// available.
// Returns the current footprint/physical/private/shared memory usage of the
// task with |task_id| in bytes. A value of -1 means no valid value is
// currently available.
virtual int64_t GetMemoryFootprintUsage(TaskId task_id) const = 0;
virtual int64_t GetPhysicalMemoryUsage(TaskId task_id) const = 0;
virtual int64_t GetPrivateMemoryUsage(TaskId task_id) const = 0;
virtual int64_t GetSharedMemoryUsage(TaskId task_id) const = 0;
......
......@@ -50,8 +50,12 @@ enum RefreshType {
REFRESH_TYPE_MEMORY_STATE = 1 << 15,
REFRESH_TYPE_KEEPALIVE_COUNT = 1 << 16,
REFRESH_TYPE_MEMORY_FOOTPRINT = 1 << 17,
REFRESH_TYPE_MEMORY =
REFRESH_TYPE_MEMORY = REFRESH_TYPE_PHYSICAL_MEMORY |
REFRESH_TYPE_MEMORY_FOOTPRINT |
REFRESH_TYPE_MEMORY_DETAILS,
REFRESH_TYPE_MEMORY_NON_MEMORY_INSTRUMENTATION =
REFRESH_TYPE_PHYSICAL_MEMORY | REFRESH_TYPE_MEMORY_DETAILS,
};
......
......@@ -102,6 +102,9 @@ void TaskManagerTester::ToggleColumnVisibility(ColumnSpecifier column) {
case ColumnSpecifier::PROCESS_ID:
column_id = IDS_TASK_MANAGER_PROCESS_ID_COLUMN;
break;
case ColumnSpecifier::MEMORY_FOOTPRINT:
column_id = IDS_TASK_MANAGER_MEM_FOOTPRINT_COLUMN;
break;
case ColumnSpecifier::PHYSICAL_MEMORY:
column_id = IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN;
break;
......@@ -136,6 +139,10 @@ int64_t TaskManagerTester::GetColumnValue(ColumnSpecifier column, int row) {
case ColumnSpecifier::COLUMN_NONE:
case ColumnSpecifier::MEMORY_STATE:
break;
case ColumnSpecifier::MEMORY_FOOTPRINT:
value = task_manager()->GetMemoryFootprintUsage(task_id);
success = true;
break;
case ColumnSpecifier::PHYSICAL_MEMORY:
value = task_manager()->GetPhysicalMemoryUsage(task_id);
success = true;
......
......@@ -38,6 +38,10 @@ base::TimeDelta TestTaskManager::GetCpuTime(TaskId task_id) const {
return base::TimeDelta();
}
int64_t TestTaskManager::GetMemoryFootprintUsage(TaskId task_id) const {
return -1;
}
int64_t TestTaskManager::GetPhysicalMemoryUsage(TaskId task_id) const {
return -1;
}
......
......@@ -29,6 +29,7 @@ class TestTaskManager : public TaskManagerInterface {
double GetPlatformIndependentCPUUsage(TaskId task_id) const override;
base::Time GetStartTime(TaskId task_id) const override;
base::TimeDelta GetCpuTime(TaskId task_id) const override;
int64_t GetMemoryFootprintUsage(TaskId task_id) const override;
int64_t GetPhysicalMemoryUsage(TaskId task_id) const override;
int64_t GetPrivateMemoryUsage(TaskId task_id) const override;
int64_t GetSharedMemoryUsage(TaskId task_id) const override;
......
......@@ -26,8 +26,11 @@ const TableColumnData kColumns[] = {
true, true},
{IDS_TASK_MANAGER_PROFILE_NAME_COLUMN, ui::TableColumn::LEFT, -1, 0, 60,
200, true, true, false},
{IDS_TASK_MANAGER_MEM_FOOTPRINT_COLUMN, ui::TableColumn::RIGHT, -1, 0,
arraysize("800 MiB") * kCharWidth,
arraysize("Memory Footprint") * 1.5 * kCharWidth, true, false, true},
{IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN, ui::TableColumn::RIGHT, -1, 0,
arraysize("800 MiB") * kCharWidth, -1, true, false, true},
arraysize("800 MiB") * kCharWidth, -1, true, false, false},
{IDS_TASK_MANAGER_SHARED_MEM_COLUMN, ui::TableColumn::RIGHT, -1, 0,
arraysize("800 MiB") * kCharWidth, -1, true, false, false},
{IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN, ui::TableColumn::RIGHT, -1, 0,
......@@ -112,6 +115,7 @@ std::string GetColumnIdAsString(int column_id) {
switch (column_id) {
COLUMN_CASE(IDS_TASK_MANAGER_TASK_COLUMN);
COLUMN_CASE(IDS_TASK_MANAGER_PROFILE_NAME_COLUMN);
COLUMN_CASE(IDS_TASK_MANAGER_MEM_FOOTPRINT_COLUMN);
COLUMN_CASE(IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN);
COLUMN_CASE(IDS_TASK_MANAGER_SHARED_MEM_COLUMN);
COLUMN_CASE(IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN);
......
......@@ -48,6 +48,7 @@ const int64_t kRefreshTimeMS = 1000;
// only once per group.
bool IsSharedByGroup(int column_id) {
switch (column_id) {
case IDS_TASK_MANAGER_MEM_FOOTPRINT_COLUMN:
case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
......@@ -363,6 +364,10 @@ base::string16 TaskManagerTableModel::GetText(int row, int column) {
return stringifier_->GetStartTimeText(
observed_task_manager()->GetStartTime(tasks_[row]));
case IDS_TASK_MANAGER_MEM_FOOTPRINT_COLUMN:
return stringifier_->GetMemoryUsageText(
observed_task_manager()->GetMemoryFootprintUsage(tasks_[row]), false);
case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
return stringifier_->GetMemoryUsageText(
observed_task_manager()->GetPrivateMemoryUsage(tasks_[row]), false);
......@@ -516,6 +521,11 @@ int TaskManagerTableModel::CompareValues(int row1,
return ValueCompare(observed_task_manager()->GetStartTime(tasks_[row1]),
observed_task_manager()->GetStartTime(tasks_[row2]));
case IDS_TASK_MANAGER_MEM_FOOTPRINT_COLUMN:
return ValueCompare(
observed_task_manager()->GetMemoryFootprintUsage(tasks_[row1]),
observed_task_manager()->GetMemoryFootprintUsage(tasks_[row2]));
case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
return ValueCompare(
observed_task_manager()->GetPrivateMemoryUsage(tasks_[row1]),
......@@ -726,15 +736,20 @@ void TaskManagerTableModel::UpdateRefreshTypes(int column_id, bool visibility) {
type = REFRESH_TYPE_CPU_TIME;
break;
case IDS_TASK_MANAGER_MEM_FOOTPRINT_COLUMN:
type = REFRESH_TYPE_MEMORY_FOOTPRINT;
break;
case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
type = REFRESH_TYPE_PHYSICAL_MEMORY;
break;
case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
case IDS_TASK_MANAGER_SWAPPED_MEM_COLUMN:
type = REFRESH_TYPE_MEMORY_DETAILS;
if (table_view_delegate_->IsColumnVisible(
IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN) ||
table_view_delegate_->IsColumnVisible(
IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN) ||
table_view_delegate_->IsColumnVisible(
IDS_TASK_MANAGER_SHARED_MEM_COLUMN) ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment