Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(304)

Side by Side Diff: chrome/browser/memory/tab_manager.cc

Issue 2350423003: [Tentaive patch for discussion] Add Purge+Suspend metrics as UMA.
Patch Set: Add UMA to tab_manager Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/memory/tab_manager.h" 5 #include "chrome/browser/memory/tab_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <set> 10 #include <set>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/feature_list.h" 16 #include "base/feature_list.h"
17 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/memory/memory_pressure_monitor.h" 18 #include "base/memory/memory_pressure_monitor.h"
19 #include "base/metrics/field_trial.h" 19 #include "base/metrics/field_trial.h"
20 #include "base/metrics/histogram_macros.h" 20 #include "base/metrics/histogram_macros.h"
21 #include "base/observer_list.h" 21 #include "base/observer_list.h"
22 #include "base/process/process.h" 22 #include "base/process/process.h"
23 #include "base/process/process_metrics.h"
23 #include "base/strings/string16.h" 24 #include "base/strings/string16.h"
24 #include "base/strings/string_number_conversions.h" 25 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/string_util.h" 26 #include "base/strings/string_util.h"
26 #include "base/strings/utf_string_conversions.h" 27 #include "base/strings/utf_string_conversions.h"
27 #include "base/threading/thread.h" 28 #include "base/threading/thread.h"
28 #include "base/threading/thread_task_runner_handle.h" 29 #include "base/threading/thread_task_runner_handle.h"
29 #include "base/time/tick_clock.h" 30 #include "base/time/tick_clock.h"
30 #include "build/build_config.h" 31 #include "build/build_config.h"
31 #include "chrome/browser/browser_process.h" 32 #include "chrome/browser/browser_process.h"
32 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" 33 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 664
664 #if defined(OS_CHROMEOS) 665 #if defined(OS_CHROMEOS)
665 TabStatsList stats_list = GetTabStats(); 666 TabStatsList stats_list = GetTabStats();
666 // This starts the CrOS specific OOM adjustments in /proc/<pid>/oom_score_adj. 667 // This starts the CrOS specific OOM adjustments in /proc/<pid>/oom_score_adj.
667 delegate_->AdjustOomPriorities(stats_list); 668 delegate_->AdjustOomPriorities(stats_list);
668 #endif 669 #endif
669 670
670 PurgeAndSuspendBackgroundedTabs(); 671 PurgeAndSuspendBackgroundedTabs();
671 } 672 }
672 673
674 bool TabManager::CanPurgeAndSuspendBackgroundedTab(
675 int64_t target_web_contents_id) const {
676 TabStripModel* model;
677 int idx = FindTabStripModelById(target_web_contents_id, &model);
678
679 if (idx == -1)
680 return false;
681
682 WebContents* web_contents = model->GetWebContentsAt(idx);
683
684 // Do not suspend tabs that are playing either playing audio or accessing the
685 // microphone or camera as it's too distruptive to the user experience.
686 if (IsMediaTab(web_contents))
687 return false;
688
689 if (web_contents->GetContentsMimeType() == "application/pdf")
690 return false;
691
692 // Do not purge and suspend a tab that was explicitly disallowed to.
693 // Note: reused tab discarding logic.
694 if (!IsTabAutoDiscardable(web_contents))
695 return false;
696
697 return true;
698 }
699
700 void TabManager::RecordPurgeAndSuspendMetrics(
701 const base::ProcessHandle& handle) {
702 std::unique_ptr<base::ProcessMetrics> process_metrics(
703 base::ProcessMetrics::CreateProcessMetrics(handle));
704 size_t private_bytes, shared_bytes;
705 if (process_metrics->GetMemoryBytes(&private_bytes, &shared_bytes)) {
706 UMA_HISTOGRAM_MEMORY_KB("Memory.PurgeAndSuspend.PrivateBytesKB",
707 private_bytes);
708 UMA_HISTOGRAM_MEMORY_KB("Memory.PurgeAndSuspend.SharedBytesKB",
709 shared_bytes);
710 }
711 }
712
673 void TabManager::PurgeAndSuspendBackgroundedTabs() { 713 void TabManager::PurgeAndSuspendBackgroundedTabs() {
674 const base::CommandLine& command_line = 714 const base::CommandLine& command_line =
675 *base::CommandLine::ForCurrentProcess(); 715 *base::CommandLine::ForCurrentProcess();
676 if (!command_line.HasSwitch(switches::kPurgeAndSuspendTime)) 716 if (!command_line.HasSwitch(switches::kPurgeAndSuspendTime))
677 return; 717 return;
678 int purge_and_suspend_time = 0; 718 int purge_and_suspend_time = 0;
679 if (!base::StringToInt( 719 if (!base::StringToInt(
680 command_line.GetSwitchValueASCII(switches::kPurgeAndSuspendTime), 720 command_line.GetSwitchValueASCII(switches::kPurgeAndSuspendTime),
681 &purge_and_suspend_time)) { 721 &purge_and_suspend_time)) {
682 return; 722 return;
683 } 723 }
684 if (purge_and_suspend_time <= 0) 724 if (purge_and_suspend_time <= 0)
685 return; 725 return;
686 auto purge_and_suspend_time_threshold = 726 auto purge_and_suspend_time_threshold =
687 NowTicks() - base::TimeDelta::FromSeconds(purge_and_suspend_time); 727 NowTicks() - base::TimeDelta::FromSeconds(purge_and_suspend_time);
688 auto tab_stats = GetUnsortedTabStats(); 728 auto tab_stats = GetUnsortedTabStats();
689 for (auto& tab : tab_stats) { 729 for (auto& tab : tab_stats) {
690 if (!tab.render_process_host->IsProcessBackgrounded()) 730 if (!tab.render_process_host->IsProcessBackgrounded())
691 continue; 731 continue;
692 // TODO(hajimehoshi): Now calling PurgeAndSuspend is implemented without 732 // TODO(hajimehoshi): Now calling PurgeAndSuspend is implemented without
693 // timers for simplicity, so PurgeAndSuspend is called even after the 733 // timers for simplicity, so PurgeAndSuspend is called even after the
694 // renderer is purged and suspended once. This should be replaced with 734 // renderer is purged and suspended once. This should be replaced with
695 // timers if we want necessary and sufficient signals. 735 // timers if we want necessary and sufficient signals.
696 if (tab.last_active > purge_and_suspend_time_threshold) 736 if (tab.last_active > purge_and_suspend_time_threshold)
697 continue; 737 continue;
698 tab.render_process_host->PurgeAndSuspend(); 738
739 if (CanPurgeAndSuspendBackgroundedTab(tab.tab_contents_id))
740 continue;
741
742 if (tab.render_process_host->GetLastPurgeAndSuspendTime() <
743 tab.last_active) {
744 // If purge_and_suspend is disabled, PurgeAndSuspend() just updates
745 // LastPurgeAndSuspendTime. So we can avoid invoking
746 // RecordPurgeAndSuspendMetrics twice.
747 tab.render_process_host->PurgeAndSuspend();
748
749 if (!task_runner_.get())
750 task_runner_ = base::ThreadTaskRunnerHandle::Get();
751 task_runner_->PostDelayedTask(
752 FROM_HERE,
753 base::Bind(&TabManager::RecordPurgeAndSuspendMetrics,
754 base::Unretained(this),
755 base::ConstRef(tab.render_process_host->GetHandle())),
756 base::TimeDelta::FromSeconds(15));
757 }
699 } 758 }
700 } 759 }
701 760
702 WebContents* TabManager::DiscardWebContentsAt(int index, TabStripModel* model) { 761 WebContents* TabManager::DiscardWebContentsAt(int index, TabStripModel* model) {
703 // Can't discard active index. 762 // Can't discard active index.
704 if (model->active_index() == index) 763 if (model->active_index() == index)
705 return nullptr; 764 return nullptr;
706 765
707 WebContents* old_contents = model->GetWebContentsAt(index); 766 WebContents* old_contents = model->GetWebContentsAt(index);
708 767
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 // platform. 999 // platform.
941 std::string allow_multiple_discards = variations::GetVariationParamValue( 1000 std::string allow_multiple_discards = variations::GetVariationParamValue(
942 features::kAutomaticTabDiscarding.name, "AllowMultipleDiscards"); 1001 features::kAutomaticTabDiscarding.name, "AllowMultipleDiscards");
943 return (allow_multiple_discards != "true"); 1002 return (allow_multiple_discards != "true");
944 #else 1003 #else
945 return false; 1004 return false;
946 #endif 1005 #endif
947 } 1006 }
948 1007
949 } // namespace memory 1008 } // namespace memory
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698