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

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

Issue 2095413002: TabManagerDelegate: Better prioritize ARC processes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more review commments.. Created 4 years, 5 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_delegate_chromeos.h" 5 #include "chrome/browser/memory/tab_manager_delegate_chromeos.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 69
70 // Checks if a window renders ARC apps. 70 // Checks if a window renders ARC apps.
71 bool IsArcWindow(aura::Window* window) { 71 bool IsArcWindow(aura::Window* window) {
72 if (!window || window->name() != kExoShellSurfaceWindowName) 72 if (!window || window->name() != kExoShellSurfaceWindowName)
73 return false; 73 return false;
74 std::string application_id = exo::ShellSurface::GetApplicationId(window); 74 std::string application_id = exo::ShellSurface::GetApplicationId(window);
75 return base::StartsWith(application_id, kArcProcessNamePrefix, 75 return base::StartsWith(application_id, kArcProcessNamePrefix,
76 base::CompareCase::SENSITIVE); 76 base::CompareCase::SENSITIVE);
77 } 77 }
78 78
79 bool IsArcWindowInForeground() {
80 auto activation_client = GetActivationClient();
81 return activation_client && IsArcWindow(activation_client->GetActiveWindow());
82 }
83
84 int AppStateToPriority(
85 const arc::mojom::ProcessState& process_state) {
86 // Logic copied from Android:
87 // frameworks/base/core/java/android/app/ActivityManager.java
88 // Note that ProcessState enumerates from most important (lower value) to
89 // least important (higher value), while ProcessPriority enumerates the
90 // opposite.
91 if (process_state >= arc::mojom::ProcessState::HOME) {
92 return ProcessPriority::ANDROID_BACKGROUND;
93 } else if (process_state >= arc::mojom::ProcessState::SERVICE) {
94 return ProcessPriority::ANDROID_SERVICE;
95 } else if (process_state >= arc::mojom::ProcessState::HEAVY_WEIGHT) {
96 return ProcessPriority::ANDROID_CANT_SAVE_STATE;
97 } else if (process_state >= arc::mojom::ProcessState::IMPORTANT_BACKGROUND) {
98 return ProcessPriority::ANDROID_PERCEPTIBLE;
99 } else if (process_state >= arc::mojom::ProcessState::IMPORTANT_FOREGROUND) {
100 return ProcessPriority::ANDROID_VISIBLE;
101 } else if (process_state >= arc::mojom::ProcessState::TOP_SLEEPING) {
102 return ProcessPriority::ANDROID_TOP_SLEEPING;
103 } else if (process_state >= arc::mojom::ProcessState::FOREGROUND_SERVICE) {
104 return ProcessPriority::ANDROID_FOREGROUND_SERVICE;
105 } else if (process_state >= arc::mojom::ProcessState::TOP) {
106 return IsArcWindowInForeground() ?
107 ProcessPriority::ANDROID_TOP :
108 ProcessPriority::ANDROID_TOP_INACTIVE;
109 } else if (process_state >= arc::mojom::ProcessState::PERSISTENT) {
110 return ProcessPriority::ANDROID_PERSISTENT;
111 }
112 return ProcessPriority::ANDROID_NON_EXISTS;
113 }
114
115 int TabStatsToPriority(const TabStats& tab) {
116 if (tab.is_selected)
117 return ProcessPriority::CHROME_SELECTED;
118
119 int priority = 0;
120
121 if (tab.is_app) {
122 priority = ProcessPriority::CHROME_APP;
123 } else if (tab.is_internal_page) {
124 priority = ProcessPriority::CHROME_INTERNAL;
125 } else {
126 priority = ProcessPriority::CHROME_NORMAL;
127 }
128 if (tab.is_pinned)
129 priority |= ProcessPriority::CHROME_PINNED;
130 if (tab.is_media)
131 priority |= ProcessPriority::CHROME_MEDIA;
132 if (tab.has_form_entry)
133 priority |= ProcessPriority::CHROME_CANT_SAVE_STATE;
134
135 return priority;
136 }
137
138 bool IsArcMemoryManagementEnabled() { 79 bool IsArcMemoryManagementEnabled() {
139 return base::FeatureList::IsEnabled(features::kArcMemoryManagement); 80 return base::FeatureList::IsEnabled(features::kArcMemoryManagement);
140 } 81 }
141 82
142 } // namespace 83 } // namespace
143 84
85 std::ostream& operator<<(std::ostream& os, const ProcessType& type) {
86 switch (type) {
87 case ProcessType::FOCUSED_APP:
88 os << "FOCUSED_APP/FOCUSED_TAB";
Luis Héctor Chávez 2016/07/22 03:01:43 style nit: having "return os << ..." saves you one
cylee1 2016/07/22 22:18:43 Done.
89 break;
90 case ProcessType::VISIBLE_APP:
91 os << "VISIBLE_APP";
92 break;
93 case ProcessType::BACKGROUND_APP:
94 os << "BACKGROUND_APP";
95 break;
96 case ProcessType::BACKGROUND_TAB:
97 os << "BACKGROUND_TAB";
98 break;
99 case ProcessType::UNKNOWN_TYPE:
100 os << "UNKNOWN_TYPE";
101 break;
102 default:
103 os << "NOT_IMPLEMENTED_ERROR";
104 }
105 return os;
106 }
107
108 // TabManagerDelegate::Candidate implementation.
144 std::ostream& operator<<( 109 std::ostream& operator<<(
145 std::ostream& out, const TabManagerDelegate::Candidate& candidate) { 110 std::ostream& out, const TabManagerDelegate::Candidate& candidate) {
146 if (candidate.is_arc_app) { 111 if (candidate.app()) {
147 out << "app " << candidate.app->pid() 112 out << "app " << candidate.app()->pid() << " ("
148 << " (" << candidate.app->process_name() << ")"; 113 << candidate.app()->process_name() << ")"
149 } else { 114 << ", process_state " << candidate.app()->process_state()
150 out << "tab " << candidate.tab->renderer_handle; 115 << ", is_focused " << candidate.app()->is_focused()
116 << ", lastActivityTime " << candidate.app()->last_activity_time();
117 } else if (candidate.tab()) {
118 out << "tab " << candidate.tab()->renderer_handle;
151 } 119 }
152 out << " with priority " << candidate.priority; 120 out << ", process_type " << candidate.process_type();
153 return out; 121 return out;
154 } 122 }
155 123
124 TabManagerDelegate::Candidate& TabManagerDelegate::Candidate::operator=(
125 TabManagerDelegate::Candidate&& other) {
126 tab_ = other.tab_;
127 app_ = other.app_;
128 process_type_ = other.process_type_;
129 return *this;
130 }
131
132 bool TabManagerDelegate::Candidate::operator<(
133 const TabManagerDelegate::Candidate& rhs) const {
134 if (process_type() != rhs.process_type())
135 return process_type() < rhs.process_type();
136 if (app() && rhs.app())
137 return *app() < *rhs.app();
138 if (tab() && rhs.tab())
139 return TabManager::CompareTabStats(*tab(), *rhs.tab());
140 // Impossible case. If app and tab are mixed in one process type, favor
141 // apps.
142 NOTREACHED() << "Undefined comparison between apps and tabs";
143 return app();
144 }
145
146 ProcessType TabManagerDelegate::Candidate::GetProcessTypeInternal() const {
147 if (app()) {
148 if (app()->is_focused())
149 return ProcessType::FOCUSED_APP;
150 if (app()->process_state() == arc::mojom::ProcessState::TOP)
151 return ProcessType::VISIBLE_APP;
152 return ProcessType::BACKGROUND_APP;
153 }
154 if (tab()) {
155 if (tab()->is_selected)
156 return ProcessType::FOCUSED_TAB;
157 return ProcessType::BACKGROUND_TAB;
158 }
159 NOTREACHED() << "Unexpected process type";
160 return ProcessType::UNKNOWN_TYPE;
161 }
162
156 // Holds the info of a newly focused tab or app window. The focused process is 163 // Holds the info of a newly focused tab or app window. The focused process is
157 // set to highest priority (lowest OOM score), but not immediately. To avoid 164 // set to highest priority (lowest OOM score), but not immediately. To avoid
158 // redundant settings the OOM score adjusting only happens after a timeout. If 165 // redundant settings the OOM score adjusting only happens after a timeout. If
159 // the process loses focus before the timeout, the adjustment is canceled. 166 // the process loses focus before the timeout, the adjustment is canceled.
160 // 167 //
161 // This information might be set on UI thread and looked up on FILE thread. So a 168 // This information might be set on UI thread and looked up on FILE thread. So a
162 // lock is needed to avoid racing. 169 // lock is needed to avoid racing.
163 class TabManagerDelegate::FocusedProcess { 170 class TabManagerDelegate::FocusedProcess {
164 public: 171 public:
165 static const int kInvalidArcAppNspid = 0; 172 static const int kInvalidArcAppNspid = 0;
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 } 405 }
399 VLOG(2) << "Disable LowMemoryKiller"; 406 VLOG(2) << "Disable LowMemoryKiller";
400 arc_process_instance_->DisableLowMemoryKiller(); 407 arc_process_instance_->DisableLowMemoryKiller();
401 } 408 }
402 409
403 void TabManagerDelegate::OnInstanceClosed() { 410 void TabManagerDelegate::OnInstanceClosed() {
404 arc_process_instance_ = nullptr; 411 arc_process_instance_ = nullptr;
405 arc_process_instance_version_ = 0; 412 arc_process_instance_version_ = 0;
406 } 413 }
407 414
415 // TODO(cylee): Remove this function if Android process OOM score settings
416 // is moved back to Android.
417 // For example, negotiate non-overlapping OOM score ranges so Chrome and Android
418 // can set OOM score for processes in their own world.
408 void TabManagerDelegate::OnWindowActivated( 419 void TabManagerDelegate::OnWindowActivated(
409 aura::client::ActivationChangeObserver::ActivationReason reason, 420 aura::client::ActivationChangeObserver::ActivationReason reason,
410 aura::Window* gained_active, 421 aura::Window* gained_active,
411 aura::Window* lost_active) { 422 aura::Window* lost_active) {
412 if (IsArcWindow(gained_active)) { 423 if (IsArcWindow(gained_active)) {
413 // Currently there is no way to know which app is displayed in the ARC 424 // Currently there is no way to know which app is displayed in the ARC
414 // window, so schedule an early adjustment for all processes to reflect 425 // window, so schedule an early adjustment for all processes to reflect
415 // the change. 426 // the change.
416 // Put a dummy FocusedProcess with nspid = kInvalidArcAppNspid for now to 427 // Put a dummy FocusedProcess with nspid = kInvalidArcAppNspid for now to
417 // indicate the focused process is an arc app. 428 // indicate the focused process is an arc app.
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 base::Bind(&TabManagerDelegate::AdjustOomPrioritiesImpl, 602 base::Bind(&TabManagerDelegate::AdjustOomPrioritiesImpl,
592 weak_ptr_factory_.GetWeakPtr(), tab_list))) { 603 weak_ptr_factory_.GetWeakPtr(), tab_list))) {
593 return; 604 return;
594 } 605 }
595 } 606 }
596 // Pass in a dummy list if unable to get ARC processes. 607 // Pass in a dummy list if unable to get ARC processes.
597 AdjustOomPrioritiesImpl(tab_list, std::vector<arc::ArcProcess>()); 608 AdjustOomPrioritiesImpl(tab_list, std::vector<arc::ArcProcess>());
598 } 609 }
599 610
600 // Excludes persistent ARC apps, but still preserves active chrome tabs and 611 // Excludes persistent ARC apps, but still preserves active chrome tabs and
601 // top ARC apps. The latter ones should not be killed by TabManager since 612 // focused ARC apps. The latter ones should not be killed by TabManager here,
602 // we still want to adjust their oom_score_adj. 613 // but we want to adjust their oom_score_adj.
603 // static 614 // static
604 std::vector<TabManagerDelegate::Candidate> 615 std::vector<TabManagerDelegate::Candidate>
605 TabManagerDelegate::GetSortedCandidates( 616 TabManagerDelegate::GetSortedCandidates(
606 const TabStatsList& tab_list, 617 const TabStatsList& tab_list,
607 const std::vector<arc::ArcProcess>& arc_processes) { 618 const std::vector<arc::ArcProcess>& arc_processes) {
619 static constexpr char kAppLauncherProcessName[] =
620 "org.chromium.arc.applauncher";
608 621
609 std::vector<Candidate> candidates; 622 std::vector<Candidate> candidates;
610 candidates.reserve(tab_list.size() + arc_processes.size()); 623 candidates.reserve(tab_list.size() + arc_processes.size());
611 624
612 for (const auto& tab : tab_list) { 625 for (const auto& tab : tab_list) {
613 candidates.push_back(Candidate(&tab, TabStatsToPriority(tab))); 626 candidates.push_back(Candidate(&tab));
Luis Héctor Chávez 2016/07/22 03:01:43 nit: can all the calls to candidates.push_back(Can
cylee1 2016/07/22 22:18:43 Done.
614 } 627 }
615 628
616 for (const auto& app : arc_processes) { 629 for (const auto& app : arc_processes) {
617 Candidate candidate(&app, AppStateToPriority(app.process_state())); 630 // Skip persistent android processes since they should never be killed here.
618 // Skip persistent android processes since we should never kill them. 631 // Neither do we set their OOM scores so their score remains minimum.
619 // Also don't ajust OOM score so their score remains min oom_score_adj. 632 //
620 if (candidate.priority >= ProcessPriority::ANDROID_PERSISTENT) 633 // AppLauncher is treated specially in ARC++. For example it is taken
634 // as the dummy foreground app from Android's point of view when the focused
635 // window is not an Android app. We prefer never kill it.
636 if (app.process_state() <= arc::mojom::ProcessState::PERSISTENT_UI ||
637 app.process_name() == kAppLauncherProcessName)
621 continue; 638 continue;
622 candidates.push_back(candidate); 639 candidates.push_back(Candidate(&app));
623 } 640 }
624 641
625 // Sort candidates according to priority. 642 // Sort candidates according to priority.
626 // TODO(cylee): Missing LRU property. Fix it when apps has the information.
627 std::sort(candidates.begin(), candidates.end()); 643 std::sort(candidates.begin(), candidates.end());
628 644
629 return candidates; 645 return candidates;
630 } 646 }
631 647
632 bool TabManagerDelegate::KillArcProcess(const int nspid) { 648 bool TabManagerDelegate::KillArcProcess(const int nspid) {
633 if (!arc_process_instance_) 649 if (!arc_process_instance_)
634 return false; 650 return false;
635 arc_process_instance_->KillProcess(nspid, "LowMemoryKill"); 651 arc_process_instance_->KillProcess(nspid, "LowMemoryKill");
636 return true; 652 return true;
637 } 653 }
638 654
639 bool TabManagerDelegate::KillTab(int64_t tab_id) { 655 bool TabManagerDelegate::KillTab(int64_t tab_id) {
640 // Check |tab_manager_| is alive before taking tabs into consideration. 656 // Check |tab_manager_| is alive before taking tabs into consideration.
641 return tab_manager_ && 657 return tab_manager_ &&
642 tab_manager_->CanDiscardTab(tab_id) && 658 tab_manager_->CanDiscardTab(tab_id) &&
643 tab_manager_->DiscardTabById(tab_id); 659 tab_manager_->DiscardTabById(tab_id);
644 } 660 }
645 661
646 void TabManagerDelegate::LowMemoryKillImpl( 662 void TabManagerDelegate::LowMemoryKillImpl(
647 const TabStatsList& tab_list, 663 const TabStatsList& tab_list,
648 const std::vector<arc::ArcProcess>& arc_processes) { 664 const std::vector<arc::ArcProcess>& arc_processes) {
649 665
650 VLOG(2) << "LowMemoryKilleImpl"; 666 VLOG(2) << "LowMemoryKilleImpl";
651 std::vector<TabManagerDelegate::Candidate> candidates = 667 const std::vector<TabManagerDelegate::Candidate> candidates =
652 GetSortedCandidates(tab_list, arc_processes); 668 GetSortedCandidates(tab_list, arc_processes);
653 669
654 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB(); 670 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB();
655 for (const auto& entry : candidates) { 671 // Kill processes until the estimated amount of freed memory is sufficient to
672 // bring the system memory back to a normal level.
673 // The list is sorted by descending importance, so we go through the list
674 // backwards.
675 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) {
656 VLOG(3) << "Target memory to free: " << target_memory_to_free_kb << " KB"; 676 VLOG(3) << "Target memory to free: " << target_memory_to_free_kb << " KB";
657 // Never kill selected tab or Android foreground app, regardless whether 677 // Never kill selected tab or Android foreground app, regardless whether
658 // they're in the active window. Since the user experience would be bad. 678 // they're in the active window. Since the user experience would be bad.
659 if ((!entry.is_arc_app && 679 ProcessType process_type = it->process_type();
660 entry.priority >= ProcessPriority::CHROME_SELECTED) || 680 if (process_type == ProcessType::VISIBLE_APP ||
661 (entry.is_arc_app && 681 process_type == ProcessType::FOCUSED_APP ||
662 entry.priority >= ProcessPriority::ANDROID_TOP_INACTIVE)) { 682 process_type == ProcessType::FOCUSED_TAB) {
663 VLOG(2) << "Skipped killing " << entry; 683 VLOG(2) << "Skipped killing " << *it;
664 continue; 684 continue;
665 } 685 }
666 if (entry.is_arc_app) { 686 if (it->app()) {
667 int estimated_memory_freed_kb = 687 int estimated_memory_freed_kb =
668 mem_stat_->EstimatedMemoryFreedKB(entry.app->pid()); 688 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid());
669 if (KillArcProcess(entry.app->nspid())) { 689 if (KillArcProcess(it->app()->nspid())) {
670 target_memory_to_free_kb -= estimated_memory_freed_kb; 690 target_memory_to_free_kb -= estimated_memory_freed_kb;
671 uma_->ReportKill(estimated_memory_freed_kb); 691 uma_->ReportKill(estimated_memory_freed_kb);
672 VLOG(2) << "Killed " << entry; 692 VLOG(2) << "Killed " << *it;
673 } 693 }
674 } else { 694 } else {
675 int64_t tab_id = entry.tab->tab_contents_id; 695 int64_t tab_id = it->tab()->tab_contents_id;
676 int estimated_memory_freed_kb = 696 int estimated_memory_freed_kb =
677 mem_stat_->EstimatedMemoryFreedKB(entry.tab->renderer_handle); 697 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle);
678 if (KillTab(tab_id)) { 698 if (KillTab(tab_id)) {
679 target_memory_to_free_kb -= estimated_memory_freed_kb; 699 target_memory_to_free_kb -= estimated_memory_freed_kb;
680 uma_->ReportKill(estimated_memory_freed_kb); 700 uma_->ReportKill(estimated_memory_freed_kb);
681 VLOG(2) << "Killed " << entry; 701 VLOG(2) << "Killed " << *it;
682 } 702 }
683 } 703 }
684 if (target_memory_to_free_kb < 0) 704 if (target_memory_to_free_kb < 0)
685 break; 705 break;
686 } 706 }
687 } 707 }
688 708
689 void TabManagerDelegate::AdjustOomPrioritiesImpl( 709 void TabManagerDelegate::AdjustOomPrioritiesImpl(
690 const TabStatsList& tab_list, 710 const TabStatsList& tab_list,
691 const std::vector<arc::ArcProcess>& arc_processes) { 711 const std::vector<arc::ArcProcess>& arc_processes) {
692 // Least important first. 712 // Least important first.
693 auto candidates = GetSortedCandidates(tab_list, arc_processes); 713 const auto candidates = GetSortedCandidates(tab_list, arc_processes);
694 714
695 // Now we assign priorities based on the sorted list. We're assigning 715 // Now we assign priorities based on the sorted list. We're assigning
696 // priorities in the range of kLowestRendererOomScore to 716 // priorities in the range of kLowestRendererOomScore to
697 // kHighestRendererOomScore (defined in chrome_constants.h). oom_score_adj 717 // kHighestRendererOomScore (defined in chrome_constants.h). oom_score_adj
698 // takes values from -1000 to 1000. Negative values are reserved for system 718 // takes values from -1000 to 1000. Negative values are reserved for system
699 // processes, and we want to give some room below the range we're using to 719 // processes, and we want to give some room below the range we're using to
700 // allow for things that want to be above the renderers in priority, so the 720 // allow for things that want to be above the renderers in priority, so the
701 // defined range gives us some variation in priority without taking up the 721 // defined range gives us some variation in priority without taking up the
702 // whole range. In the end, however, it's a pretty arbitrary range to use. 722 // whole range. In the end, however, it's a pretty arbitrary range to use.
703 // Higher values are more likely to be killed by the OOM killer. 723 // Higher values are more likely to be killed by the OOM killer.
704 724
705 // Break the processes into 2 parts. This is to help lower the chance of 725 // Break the processes into 2 parts. This is to help lower the chance of
706 // altering OOM score for many processes on any small change. 726 // altering OOM score for many processes on any small change.
707 int range_middle = 727 int range_middle =
708 (chrome::kLowestRendererOomScore + chrome::kHighestRendererOomScore) / 2; 728 (chrome::kLowestRendererOomScore + chrome::kHighestRendererOomScore) / 2;
709 729
710 // Find some pivot point. For now processes with priority >= CHROME_INTERNAL 730 // Find some pivot point. For now processes with priority >= CHROME_INTERNAL
711 // are prone to be affected by LRU change. Taking them as "high priority" 731 // are prone to be affected by LRU change. Taking them as "high priority"
712 // processes. 732 // processes.
713 auto lower_priority_part = candidates.rend(); 733 auto lower_priority_part = candidates.end();
714 // Iterate in reverse order since the list is sorted by least importance. 734 for (auto it = candidates.begin(); it != candidates.end(); ++it) {
715 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { 735 if (it->process_type() >= ProcessType::BACKGROUND_APP) {
716 if (it->priority < ProcessPriority::CHROME_INTERNAL) {
717 lower_priority_part = it; 736 lower_priority_part = it;
718 break; 737 break;
719 } 738 }
720 } 739 }
721 740
722 ProcessScoreMap new_map; 741 ProcessScoreMap new_map;
723 742
724 // Higher priority part. 743 // Higher priority part.
725 DistributeOomScoreInRange(candidates.rbegin(), lower_priority_part, 744 DistributeOomScoreInRange(candidates.begin(), lower_priority_part,
726 chrome::kLowestRendererOomScore, range_middle, 745 chrome::kLowestRendererOomScore, range_middle,
727 &new_map); 746 &new_map);
728 // Lower priority part. 747 // Lower priority part.
729 DistributeOomScoreInRange(lower_priority_part, candidates.rend(), 748 DistributeOomScoreInRange(lower_priority_part, candidates.end(), range_middle,
730 range_middle, chrome::kHighestRendererOomScore, 749 chrome::kHighestRendererOomScore, &new_map);
731 &new_map);
732 base::AutoLock oom_score_autolock(oom_score_lock_); 750 base::AutoLock oom_score_autolock(oom_score_lock_);
733 oom_score_map_.swap(new_map); 751 oom_score_map_.swap(new_map);
734 } 752 }
735 753
736 void TabManagerDelegate::SetOomScoreAdjForApp(int nspid, int score) { 754 void TabManagerDelegate::SetOomScoreAdjForApp(int nspid, int score) {
737 if (!arc_process_instance_) 755 if (!arc_process_instance_)
738 return; 756 return;
739 if (arc_process_instance_version_ < 2) { 757 if (arc_process_instance_version_ < 2) {
740 VLOG(1) << "ProcessInstance version < 2 does not " 758 VLOG(1) << "ProcessInstance version < 2 does not "
741 "support SetOomScoreAdj() yet."; 759 "support SetOomScoreAdj() yet.";
(...skipping 13 matching lines...) Expand all
755 void TabManagerDelegate::SetOomScoreAdjForTabsOnFileThread( 773 void TabManagerDelegate::SetOomScoreAdjForTabsOnFileThread(
756 const std::vector<std::pair<base::ProcessHandle, int>>& entries) { 774 const std::vector<std::pair<base::ProcessHandle, int>>& entries) {
757 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 775 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
758 for (const auto& entry : entries) { 776 for (const auto& entry : entries) {
759 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore(entry.first, 777 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore(entry.first,
760 entry.second); 778 entry.second);
761 } 779 }
762 } 780 }
763 781
764 void TabManagerDelegate::DistributeOomScoreInRange( 782 void TabManagerDelegate::DistributeOomScoreInRange(
765 std::vector<TabManagerDelegate::Candidate>::reverse_iterator rbegin, 783 std::vector<TabManagerDelegate::Candidate>::const_iterator begin,
766 std::vector<TabManagerDelegate::Candidate>::reverse_iterator rend, 784 std::vector<TabManagerDelegate::Candidate>::const_iterator end,
767 int range_begin, 785 int range_begin,
768 int range_end, 786 int range_end,
769 ProcessScoreMap* new_map) { 787 ProcessScoreMap* new_map) {
770 // OOM score setting for tabs involves file system operation so should be 788 // OOM score setting for tabs involves file system operation so should be
771 // done on file thread. 789 // done on file thread.
772 std::vector<std::pair<base::ProcessHandle, int>> oom_score_for_tabs; 790 std::vector<std::pair<base::ProcessHandle, int>> oom_score_for_tabs;
773 791
774 // Though there might be duplicate process handles, it doesn't matter to 792 // Though there might be duplicate process handles, it doesn't matter to
775 // overestimate the number of processes here since the we don't need to 793 // overestimate the number of processes here since the we don't need to
776 // use up the full range. 794 // use up the full range.
777 int num = (rend - rbegin); 795 int num = (end - begin);
778 const float priority_increment = 796 const float priority_increment =
779 static_cast<float>(range_end - range_begin) / num; 797 static_cast<float>(range_end - range_begin) / num;
780 798
781 float priority = range_begin; 799 float priority = range_begin;
782 for (auto cur = rbegin; cur != rend; ++cur) { 800 for (auto cur = begin; cur != end; ++cur) {
783 int score = static_cast<int>(priority + 0.5f); 801 int score = static_cast<int>(priority + 0.5f);
784 if (cur->is_arc_app) { 802 if (cur->app()) {
785 // Use pid as map keys so it's globally unique. 803 // Use pid as map keys so it's globally unique.
786 (*new_map)[cur->app->pid()] = score; 804 (*new_map)[cur->app()->pid()] = score;
787 int cur_app_pid_score = 0; 805 int cur_app_pid_score = 0;
788 { 806 {
789 base::AutoLock oom_score_autolock(oom_score_lock_); 807 base::AutoLock oom_score_autolock(oom_score_lock_);
790 cur_app_pid_score = oom_score_map_[cur->app->pid()]; 808 cur_app_pid_score = oom_score_map_[cur->app()->pid()];
791 } 809 }
792 if (cur_app_pid_score != score) { 810 if (cur_app_pid_score != score) {
793 VLOG(3) << "Set OOM score " << score << " for " << *cur; 811 VLOG(3) << "Set OOM score " << score << " for " << *cur;
794 SetOomScoreAdjForApp(cur->app->nspid(), score); 812 SetOomScoreAdjForApp(cur->app()->nspid(), score);
795 } 813 }
796 } else { 814 } else {
797 base::ProcessHandle process_handle = cur->tab->renderer_handle; 815 base::ProcessHandle process_handle = cur->tab()->renderer_handle;
798 // 1. tab_list contains entries for already-discarded tabs. If the PID 816 // 1. tab_list contains entries for already-discarded tabs. If the PID
799 // (renderer_handle) is zero, we don't need to adjust the oom_score. 817 // (renderer_handle) is zero, we don't need to adjust the oom_score.
800 // 2. Only add unseen process handle so if there's multiple tab maps to 818 // 2. Only add unseen process handle so if there's multiple tab maps to
801 // the same process, the process is set to an OOM score based on its "most 819 // the same process, the process is set to an OOM score based on its "most
802 // important" tab. 820 // important" tab.
803 if (process_handle != 0 && 821 if (process_handle != 0 &&
804 new_map->find(process_handle) == new_map->end()) { 822 new_map->find(process_handle) == new_map->end()) {
805 (*new_map)[process_handle] = score; 823 (*new_map)[process_handle] = score;
806 int process_handle_score = 0; 824 int process_handle_score = 0;
807 { 825 {
808 base::AutoLock oom_score_autolock(oom_score_lock_); 826 base::AutoLock oom_score_autolock(oom_score_lock_);
809 process_handle_score = oom_score_map_[process_handle]; 827 process_handle_score = oom_score_map_[process_handle];
810 } 828 }
811 if (process_handle_score != score) { 829 if (process_handle_score != score) {
812 oom_score_for_tabs.push_back(std::make_pair(process_handle, score)); 830 oom_score_for_tabs.push_back(std::make_pair(process_handle, score));
813 VLOG(3) << "Set OOM score " << score << " for " << *cur; 831 VLOG(3) << "Set OOM score " << score << " for " << *cur;
814 } 832 }
815 } else { 833 } else {
816 continue; // Skip priority increment. 834 continue; // Skip priority increment.
817 } 835 }
818 } 836 }
819 priority += priority_increment; 837 priority += priority_increment;
820 } 838 }
821 839
822 if (oom_score_for_tabs.size()) 840 if (oom_score_for_tabs.size())
823 SetOomScoreAdjForTabs(oom_score_for_tabs); 841 SetOomScoreAdjForTabs(oom_score_for_tabs);
824 } 842 }
825 843
826 } // namespace memory 844 } // namespace memory
OLDNEW
« no previous file with comments | « chrome/browser/memory/tab_manager_delegate_chromeos.h ('k') | chrome/browser/memory/tab_manager_delegate_chromeos_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698