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

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

Issue 2350423003: [Tentaive patch for discussion] Add Purge+Suspend metrics as UMA.
Patch Set: Fixed misuse of CanPurgeAndSuspend 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 #if !defined(OS_MACOSX) || defined(OS_IOS)
703 std::unique_ptr<base::ProcessMetrics> process_metrics(
704 base::ProcessMetrics::CreateProcessMetrics(handle));
705 #else
706 std::unique_ptr<base::ProcessMetrics> process_metrics(
707 base::ProcessMetrics::CreateProcessMetrics(handle, NULL));
708 #endif
709 size_t private_bytes, shared_bytes;
710 if (process_metrics->GetMemoryBytes(&private_bytes, &shared_bytes)) {
711 UMA_HISTOGRAM_MEMORY_KB("Memory.PurgeAndSuspend.PrivateBytesKB",
712 private_bytes);
713 UMA_HISTOGRAM_MEMORY_KB("Memory.PurgeAndSuspend.SharedBytesKB",
714 shared_bytes);
715 }
716 }
717
673 void TabManager::PurgeAndSuspendBackgroundedTabs() { 718 void TabManager::PurgeAndSuspendBackgroundedTabs() {
674 const base::CommandLine& command_line = 719 const base::CommandLine& command_line =
675 *base::CommandLine::ForCurrentProcess(); 720 *base::CommandLine::ForCurrentProcess();
676 if (!command_line.HasSwitch(switches::kPurgeAndSuspendTime)) 721 if (!command_line.HasSwitch(switches::kPurgeAndSuspendTime))
677 return; 722 return;
678 int purge_and_suspend_time = 0; 723 int purge_and_suspend_time = 0;
679 if (!base::StringToInt( 724 if (!base::StringToInt(
680 command_line.GetSwitchValueASCII(switches::kPurgeAndSuspendTime), 725 command_line.GetSwitchValueASCII(switches::kPurgeAndSuspendTime),
681 &purge_and_suspend_time)) { 726 &purge_and_suspend_time)) {
682 return; 727 return;
683 } 728 }
684 if (purge_and_suspend_time <= 0) 729 if (purge_and_suspend_time <= 0)
685 return; 730 return;
686 auto purge_and_suspend_time_threshold = 731 auto purge_and_suspend_time_threshold =
687 NowTicks() - base::TimeDelta::FromSeconds(purge_and_suspend_time); 732 NowTicks() - base::TimeDelta::FromSeconds(purge_and_suspend_time);
688 auto tab_stats = GetUnsortedTabStats(); 733 auto tab_stats = GetUnsortedTabStats();
689 for (auto& tab : tab_stats) { 734 for (auto& tab : tab_stats) {
690 if (!tab.render_process_host->IsProcessBackgrounded()) 735 if (!tab.render_process_host->IsProcessBackgrounded())
691 continue; 736 continue;
692 // TODO(hajimehoshi): Now calling PurgeAndSuspend is implemented without 737 // TODO(hajimehoshi): Now calling PurgeAndSuspend is implemented without
693 // timers for simplicity, so PurgeAndSuspend is called even after the 738 // timers for simplicity, so PurgeAndSuspend is called even after the
694 // renderer is purged and suspended once. This should be replaced with 739 // renderer is purged and suspended once. This should be replaced with
695 // timers if we want necessary and sufficient signals. 740 // timers if we want necessary and sufficient signals.
696 if (tab.last_active > purge_and_suspend_time_threshold) 741 if (tab.last_active > purge_and_suspend_time_threshold)
697 continue; 742 continue;
698 tab.render_process_host->PurgeAndSuspend(); 743
744 if (!CanPurgeAndSuspendBackgroundedTab(tab.tab_contents_id))
745 continue;
746
747 if (tab.render_process_host->GetLastPurgeAndSuspendTime() <
748 tab.last_active) {
749 // If purge_and_suspend is disabled, PurgeAndSuspend() just updates
750 // LastPurgeAndSuspendTime. So we can avoid invoking
751 // RecordPurgeAndSuspendMetrics twice.
752 tab.render_process_host->PurgeAndSuspend();
753
754 if (!task_runner_.get())
755 task_runner_ = base::ThreadTaskRunnerHandle::Get();
756 task_runner_->PostDelayedTask(
757 FROM_HERE,
758 base::Bind(&TabManager::RecordPurgeAndSuspendMetrics,
759 base::Unretained(this),
760 base::ConstRef(tab.render_process_host->GetHandle())),
761 base::TimeDelta::FromSeconds(15));
762 }
699 } 763 }
700 } 764 }
701 765
702 WebContents* TabManager::DiscardWebContentsAt(int index, TabStripModel* model) { 766 WebContents* TabManager::DiscardWebContentsAt(int index, TabStripModel* model) {
703 // Can't discard active index. 767 // Can't discard active index.
704 if (model->active_index() == index) 768 if (model->active_index() == index)
705 return nullptr; 769 return nullptr;
706 770
707 WebContents* old_contents = model->GetWebContentsAt(index); 771 WebContents* old_contents = model->GetWebContentsAt(index);
708 772
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 // platform. 1004 // platform.
941 std::string allow_multiple_discards = variations::GetVariationParamValue( 1005 std::string allow_multiple_discards = variations::GetVariationParamValue(
942 features::kAutomaticTabDiscarding.name, "AllowMultipleDiscards"); 1006 features::kAutomaticTabDiscarding.name, "AllowMultipleDiscards");
943 return (allow_multiple_discards != "true"); 1007 return (allow_multiple_discards != "true");
944 #else 1008 #else
945 return false; 1009 return false;
946 #endif 1010 #endif
947 } 1011 }
948 1012
949 } // namespace memory 1013 } // namespace memory
OLDNEW
« no previous file with comments | « chrome/browser/memory/tab_manager.h ('k') | content/browser/renderer_host/render_process_host_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698