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

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: sync to ToT 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 return os << "FOCUSED_APP/FOCUSED_TAB";
89 case ProcessType::VISIBLE_APP:
90 return os << "VISIBLE_APP";
91 case ProcessType::BACKGROUND_APP:
92 return os << "BACKGROUND_APP";
93 case ProcessType::BACKGROUND_TAB:
94 return os << "BACKGROUND_TAB";
95 case ProcessType::UNKNOWN_TYPE:
96 return os << "UNKNOWN_TYPE";
97 default:
98 return os << "NOT_IMPLEMENTED_ERROR";
99 }
100 return os;
101 }
102
103 // TabManagerDelegate::Candidate implementation.
144 std::ostream& operator<<( 104 std::ostream& operator<<(
145 std::ostream& out, const TabManagerDelegate::Candidate& candidate) { 105 std::ostream& out, const TabManagerDelegate::Candidate& candidate) {
146 if (candidate.is_arc_app) { 106 if (candidate.app()) {
147 out << "app " << candidate.app->pid() 107 out << "app " << candidate.app()->pid() << " ("
148 << " (" << candidate.app->process_name() << ")"; 108 << candidate.app()->process_name() << ")"
149 } else { 109 << ", process_state " << candidate.app()->process_state()
150 out << "tab " << candidate.tab->renderer_handle; 110 << ", is_focused " << candidate.app()->is_focused()
111 << ", lastActivityTime " << candidate.app()->last_activity_time();
112 } else if (candidate.tab()) {
113 out << "tab " << candidate.tab()->renderer_handle;
151 } 114 }
152 out << " with priority " << candidate.priority; 115 out << ", process_type " << candidate.process_type();
153 return out; 116 return out;
154 } 117 }
155 118
119 TabManagerDelegate::Candidate& TabManagerDelegate::Candidate::operator=(
120 TabManagerDelegate::Candidate&& other) {
121 tab_ = other.tab_;
122 app_ = other.app_;
123 process_type_ = other.process_type_;
124 return *this;
125 }
126
127 bool TabManagerDelegate::Candidate::operator<(
128 const TabManagerDelegate::Candidate& rhs) const {
129 if (process_type() != rhs.process_type())
130 return process_type() < rhs.process_type();
131 if (app() && rhs.app())
132 return *app() < *rhs.app();
133 if (tab() && rhs.tab())
134 return TabManager::CompareTabStats(*tab(), *rhs.tab());
135 // Impossible case. If app and tab are mixed in one process type, favor
136 // apps.
137 NOTREACHED() << "Undefined comparison between apps and tabs";
138 return app();
139 }
140
141 ProcessType TabManagerDelegate::Candidate::GetProcessTypeInternal() const {
142 if (app()) {
143 if (app()->is_focused())
144 return ProcessType::FOCUSED_APP;
145 if (app()->process_state() == arc::mojom::ProcessState::TOP)
146 return ProcessType::VISIBLE_APP;
147 return ProcessType::BACKGROUND_APP;
148 }
149 if (tab()) {
150 if (tab()->is_selected)
151 return ProcessType::FOCUSED_TAB;
152 return ProcessType::BACKGROUND_TAB;
153 }
154 NOTREACHED() << "Unexpected process type";
155 return ProcessType::UNKNOWN_TYPE;
156 }
157
156 // Holds the info of a newly focused tab or app window. The focused process is 158 // 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 159 // 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 160 // redundant settings the OOM score adjusting only happens after a timeout. If
159 // the process loses focus before the timeout, the adjustment is canceled. 161 // the process loses focus before the timeout, the adjustment is canceled.
160 // 162 //
161 // This information might be set on UI thread and looked up on FILE thread. So a 163 // This information might be set on UI thread and looked up on FILE thread. So a
162 // lock is needed to avoid racing. 164 // lock is needed to avoid racing.
163 class TabManagerDelegate::FocusedProcess { 165 class TabManagerDelegate::FocusedProcess {
164 public: 166 public:
165 static const int kInvalidArcAppNspid = 0; 167 static const int kInvalidArcAppNspid = 0;
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 } 400 }
399 VLOG(2) << "Disable LowMemoryKiller"; 401 VLOG(2) << "Disable LowMemoryKiller";
400 arc_process_instance_->DisableLowMemoryKiller(); 402 arc_process_instance_->DisableLowMemoryKiller();
401 } 403 }
402 404
403 void TabManagerDelegate::OnInstanceClosed() { 405 void TabManagerDelegate::OnInstanceClosed() {
404 arc_process_instance_ = nullptr; 406 arc_process_instance_ = nullptr;
405 arc_process_instance_version_ = 0; 407 arc_process_instance_version_ = 0;
406 } 408 }
407 409
410 // TODO(cylee): Remove this function if Android process OOM score settings
411 // is moved back to Android.
412 // For example, negotiate non-overlapping OOM score ranges so Chrome and Android
413 // can set OOM score for processes in their own world.
408 void TabManagerDelegate::OnWindowActivated( 414 void TabManagerDelegate::OnWindowActivated(
409 aura::client::ActivationChangeObserver::ActivationReason reason, 415 aura::client::ActivationChangeObserver::ActivationReason reason,
410 aura::Window* gained_active, 416 aura::Window* gained_active,
411 aura::Window* lost_active) { 417 aura::Window* lost_active) {
412 if (IsArcWindow(gained_active)) { 418 if (IsArcWindow(gained_active)) {
413 // Currently there is no way to know which app is displayed in the ARC 419 // 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 420 // window, so schedule an early adjustment for all processes to reflect
415 // the change. 421 // the change.
416 // Put a dummy FocusedProcess with nspid = kInvalidArcAppNspid for now to 422 // Put a dummy FocusedProcess with nspid = kInvalidArcAppNspid for now to
417 // indicate the focused process is an arc app. 423 // 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, 597 base::Bind(&TabManagerDelegate::AdjustOomPrioritiesImpl,
592 weak_ptr_factory_.GetWeakPtr(), tab_list))) { 598 weak_ptr_factory_.GetWeakPtr(), tab_list))) {
593 return; 599 return;
594 } 600 }
595 } 601 }
596 // Pass in a dummy list if unable to get ARC processes. 602 // Pass in a dummy list if unable to get ARC processes.
597 AdjustOomPrioritiesImpl(tab_list, std::vector<arc::ArcProcess>()); 603 AdjustOomPrioritiesImpl(tab_list, std::vector<arc::ArcProcess>());
598 } 604 }
599 605
600 // Excludes persistent ARC apps, but still preserves active chrome tabs and 606 // 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 607 // focused ARC apps. The latter ones should not be killed by TabManager here,
602 // we still want to adjust their oom_score_adj. 608 // but we want to adjust their oom_score_adj.
603 // static 609 // static
604 std::vector<TabManagerDelegate::Candidate> 610 std::vector<TabManagerDelegate::Candidate>
605 TabManagerDelegate::GetSortedCandidates( 611 TabManagerDelegate::GetSortedCandidates(
606 const TabStatsList& tab_list, 612 const TabStatsList& tab_list,
607 const std::vector<arc::ArcProcess>& arc_processes) { 613 const std::vector<arc::ArcProcess>& arc_processes) {
614 static constexpr char kAppLauncherProcessName[] =
615 "org.chromium.arc.applauncher";
608 616
609 std::vector<Candidate> candidates; 617 std::vector<Candidate> candidates;
610 candidates.reserve(tab_list.size() + arc_processes.size()); 618 candidates.reserve(tab_list.size() + arc_processes.size());
611 619
612 for (const auto& tab : tab_list) { 620 for (const auto& tab : tab_list) {
613 candidates.push_back(Candidate(&tab, TabStatsToPriority(tab))); 621 candidates.emplace_back(&tab);
614 } 622 }
615 623
616 for (const auto& app : arc_processes) { 624 for (const auto& app : arc_processes) {
617 Candidate candidate(&app, AppStateToPriority(app.process_state())); 625 // Skip persistent android processes since they should never be killed here.
618 // Skip persistent android processes since we should never kill them. 626 // 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. 627 //
620 if (candidate.priority >= ProcessPriority::ANDROID_PERSISTENT) 628 // AppLauncher is treated specially in ARC++. For example it is taken
629 // as the dummy foreground app from Android's point of view when the focused
630 // window is not an Android app. We prefer never kill it.
631 if (app.process_state() <= arc::mojom::ProcessState::PERSISTENT_UI ||
632 app.process_name() == kAppLauncherProcessName)
621 continue; 633 continue;
622 candidates.push_back(candidate); 634 candidates.emplace_back(&app);
623 } 635 }
624 636
625 // Sort candidates according to priority. 637 // 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()); 638 std::sort(candidates.begin(), candidates.end());
628 639
629 return candidates; 640 return candidates;
630 } 641 }
631 642
632 bool TabManagerDelegate::KillArcProcess(const int nspid) { 643 bool TabManagerDelegate::KillArcProcess(const int nspid) {
633 if (!arc_process_instance_) 644 if (!arc_process_instance_)
634 return false; 645 return false;
635 arc_process_instance_->KillProcess(nspid, "LowMemoryKill"); 646 arc_process_instance_->KillProcess(nspid, "LowMemoryKill");
636 return true; 647 return true;
637 } 648 }
638 649
639 bool TabManagerDelegate::KillTab(int64_t tab_id) { 650 bool TabManagerDelegate::KillTab(int64_t tab_id) {
640 // Check |tab_manager_| is alive before taking tabs into consideration. 651 // Check |tab_manager_| is alive before taking tabs into consideration.
641 return tab_manager_ && 652 return tab_manager_ &&
642 tab_manager_->CanDiscardTab(tab_id) && 653 tab_manager_->CanDiscardTab(tab_id) &&
643 tab_manager_->DiscardTabById(tab_id); 654 tab_manager_->DiscardTabById(tab_id);
644 } 655 }
645 656
646 void TabManagerDelegate::LowMemoryKillImpl( 657 void TabManagerDelegate::LowMemoryKillImpl(
647 const TabStatsList& tab_list, 658 const TabStatsList& tab_list,
648 const std::vector<arc::ArcProcess>& arc_processes) { 659 const std::vector<arc::ArcProcess>& arc_processes) {
649 660
650 VLOG(2) << "LowMemoryKilleImpl"; 661 VLOG(2) << "LowMemoryKilleImpl";
651 std::vector<TabManagerDelegate::Candidate> candidates = 662 const std::vector<TabManagerDelegate::Candidate> candidates =
652 GetSortedCandidates(tab_list, arc_processes); 663 GetSortedCandidates(tab_list, arc_processes);
653 664
654 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB(); 665 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB();
655 for (const auto& entry : candidates) { 666 // Kill processes until the estimated amount of freed memory is sufficient to
667 // bring the system memory back to a normal level.
668 // The list is sorted by descending importance, so we go through the list
669 // backwards.
670 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) {
656 VLOG(3) << "Target memory to free: " << target_memory_to_free_kb << " KB"; 671 VLOG(3) << "Target memory to free: " << target_memory_to_free_kb << " KB";
657 // Never kill selected tab or Android foreground app, regardless whether 672 // Never kill selected tab or Android foreground app, regardless whether
658 // they're in the active window. Since the user experience would be bad. 673 // they're in the active window. Since the user experience would be bad.
659 if ((!entry.is_arc_app && 674 ProcessType process_type = it->process_type();
660 entry.priority >= ProcessPriority::CHROME_SELECTED) || 675 if (process_type == ProcessType::VISIBLE_APP ||
661 (entry.is_arc_app && 676 process_type == ProcessType::FOCUSED_APP ||
662 entry.priority >= ProcessPriority::ANDROID_TOP_INACTIVE)) { 677 process_type == ProcessType::FOCUSED_TAB) {
663 VLOG(2) << "Skipped killing " << entry; 678 VLOG(2) << "Skipped killing " << *it;
664 continue; 679 continue;
665 } 680 }
666 if (entry.is_arc_app) { 681 if (it->app()) {
667 int estimated_memory_freed_kb = 682 int estimated_memory_freed_kb =
668 mem_stat_->EstimatedMemoryFreedKB(entry.app->pid()); 683 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid());
669 if (KillArcProcess(entry.app->nspid())) { 684 if (KillArcProcess(it->app()->nspid())) {
670 target_memory_to_free_kb -= estimated_memory_freed_kb; 685 target_memory_to_free_kb -= estimated_memory_freed_kb;
671 uma_->ReportKill(estimated_memory_freed_kb); 686 uma_->ReportKill(estimated_memory_freed_kb);
672 VLOG(2) << "Killed " << entry; 687 VLOG(2) << "Killed " << *it;
673 } 688 }
674 } else { 689 } else {
675 int64_t tab_id = entry.tab->tab_contents_id; 690 int64_t tab_id = it->tab()->tab_contents_id;
676 int estimated_memory_freed_kb = 691 int estimated_memory_freed_kb =
677 mem_stat_->EstimatedMemoryFreedKB(entry.tab->renderer_handle); 692 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle);
678 if (KillTab(tab_id)) { 693 if (KillTab(tab_id)) {
679 target_memory_to_free_kb -= estimated_memory_freed_kb; 694 target_memory_to_free_kb -= estimated_memory_freed_kb;
680 uma_->ReportKill(estimated_memory_freed_kb); 695 uma_->ReportKill(estimated_memory_freed_kb);
681 VLOG(2) << "Killed " << entry; 696 VLOG(2) << "Killed " << *it;
682 } 697 }
683 } 698 }
684 if (target_memory_to_free_kb < 0) 699 if (target_memory_to_free_kb < 0)
685 break; 700 break;
686 } 701 }
687 } 702 }
688 703
689 void TabManagerDelegate::AdjustOomPrioritiesImpl( 704 void TabManagerDelegate::AdjustOomPrioritiesImpl(
690 const TabStatsList& tab_list, 705 const TabStatsList& tab_list,
691 const std::vector<arc::ArcProcess>& arc_processes) { 706 const std::vector<arc::ArcProcess>& arc_processes) {
692 // Least important first. 707 // Least important first.
693 auto candidates = GetSortedCandidates(tab_list, arc_processes); 708 const auto candidates = GetSortedCandidates(tab_list, arc_processes);
694 709
695 // Now we assign priorities based on the sorted list. We're assigning 710 // Now we assign priorities based on the sorted list. We're assigning
696 // priorities in the range of kLowestRendererOomScore to 711 // priorities in the range of kLowestRendererOomScore to
697 // kHighestRendererOomScore (defined in chrome_constants.h). oom_score_adj 712 // kHighestRendererOomScore (defined in chrome_constants.h). oom_score_adj
698 // takes values from -1000 to 1000. Negative values are reserved for system 713 // 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 714 // 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 715 // 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 716 // 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. 717 // 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. 718 // Higher values are more likely to be killed by the OOM killer.
704 719
705 // Break the processes into 2 parts. This is to help lower the chance of 720 // 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. 721 // altering OOM score for many processes on any small change.
707 int range_middle = 722 int range_middle =
708 (chrome::kLowestRendererOomScore + chrome::kHighestRendererOomScore) / 2; 723 (chrome::kLowestRendererOomScore + chrome::kHighestRendererOomScore) / 2;
709 724
710 // Find some pivot point. For now processes with priority >= CHROME_INTERNAL 725 // 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" 726 // are prone to be affected by LRU change. Taking them as "high priority"
712 // processes. 727 // processes.
713 auto lower_priority_part = candidates.rend(); 728 auto lower_priority_part = candidates.end();
714 // Iterate in reverse order since the list is sorted by least importance. 729 for (auto it = candidates.begin(); it != candidates.end(); ++it) {
715 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { 730 if (it->process_type() >= ProcessType::BACKGROUND_APP) {
716 if (it->priority < ProcessPriority::CHROME_INTERNAL) {
717 lower_priority_part = it; 731 lower_priority_part = it;
718 break; 732 break;
719 } 733 }
720 } 734 }
721 735
722 ProcessScoreMap new_map; 736 ProcessScoreMap new_map;
723 737
724 // Higher priority part. 738 // Higher priority part.
725 DistributeOomScoreInRange(candidates.rbegin(), lower_priority_part, 739 DistributeOomScoreInRange(candidates.begin(), lower_priority_part,
726 chrome::kLowestRendererOomScore, range_middle, 740 chrome::kLowestRendererOomScore, range_middle,
727 &new_map); 741 &new_map);
728 // Lower priority part. 742 // Lower priority part.
729 DistributeOomScoreInRange(lower_priority_part, candidates.rend(), 743 DistributeOomScoreInRange(lower_priority_part, candidates.end(), range_middle,
730 range_middle, chrome::kHighestRendererOomScore, 744 chrome::kHighestRendererOomScore, &new_map);
731 &new_map);
732 base::AutoLock oom_score_autolock(oom_score_lock_); 745 base::AutoLock oom_score_autolock(oom_score_lock_);
733 oom_score_map_.swap(new_map); 746 oom_score_map_.swap(new_map);
734 } 747 }
735 748
736 void TabManagerDelegate::SetOomScoreAdjForApp(int nspid, int score) { 749 void TabManagerDelegate::SetOomScoreAdjForApp(int nspid, int score) {
737 if (!arc_process_instance_) 750 if (!arc_process_instance_)
738 return; 751 return;
739 if (arc_process_instance_version_ < 2) { 752 if (arc_process_instance_version_ < 2) {
740 VLOG(1) << "ProcessInstance version < 2 does not " 753 VLOG(1) << "ProcessInstance version < 2 does not "
741 "support SetOomScoreAdj() yet."; 754 "support SetOomScoreAdj() yet.";
(...skipping 13 matching lines...) Expand all
755 void TabManagerDelegate::SetOomScoreAdjForTabsOnFileThread( 768 void TabManagerDelegate::SetOomScoreAdjForTabsOnFileThread(
756 const std::vector<std::pair<base::ProcessHandle, int>>& entries) { 769 const std::vector<std::pair<base::ProcessHandle, int>>& entries) {
757 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 770 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
758 for (const auto& entry : entries) { 771 for (const auto& entry : entries) {
759 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore(entry.first, 772 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore(entry.first,
760 entry.second); 773 entry.second);
761 } 774 }
762 } 775 }
763 776
764 void TabManagerDelegate::DistributeOomScoreInRange( 777 void TabManagerDelegate::DistributeOomScoreInRange(
765 std::vector<TabManagerDelegate::Candidate>::reverse_iterator rbegin, 778 std::vector<TabManagerDelegate::Candidate>::const_iterator begin,
766 std::vector<TabManagerDelegate::Candidate>::reverse_iterator rend, 779 std::vector<TabManagerDelegate::Candidate>::const_iterator end,
767 int range_begin, 780 int range_begin,
768 int range_end, 781 int range_end,
769 ProcessScoreMap* new_map) { 782 ProcessScoreMap* new_map) {
770 // OOM score setting for tabs involves file system operation so should be 783 // OOM score setting for tabs involves file system operation so should be
771 // done on file thread. 784 // done on file thread.
772 std::vector<std::pair<base::ProcessHandle, int>> oom_score_for_tabs; 785 std::vector<std::pair<base::ProcessHandle, int>> oom_score_for_tabs;
773 786
774 // Though there might be duplicate process handles, it doesn't matter to 787 // 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 788 // overestimate the number of processes here since the we don't need to
776 // use up the full range. 789 // use up the full range.
777 int num = (rend - rbegin); 790 int num = (end - begin);
778 const float priority_increment = 791 const float priority_increment =
779 static_cast<float>(range_end - range_begin) / num; 792 static_cast<float>(range_end - range_begin) / num;
780 793
781 float priority = range_begin; 794 float priority = range_begin;
782 for (auto cur = rbegin; cur != rend; ++cur) { 795 for (auto cur = begin; cur != end; ++cur) {
783 int score = static_cast<int>(priority + 0.5f); 796 int score = static_cast<int>(priority + 0.5f);
784 if (cur->is_arc_app) { 797 if (cur->app()) {
785 // Use pid as map keys so it's globally unique. 798 // Use pid as map keys so it's globally unique.
786 (*new_map)[cur->app->pid()] = score; 799 (*new_map)[cur->app()->pid()] = score;
787 int cur_app_pid_score = 0; 800 int cur_app_pid_score = 0;
788 { 801 {
789 base::AutoLock oom_score_autolock(oom_score_lock_); 802 base::AutoLock oom_score_autolock(oom_score_lock_);
790 cur_app_pid_score = oom_score_map_[cur->app->pid()]; 803 cur_app_pid_score = oom_score_map_[cur->app()->pid()];
791 } 804 }
792 if (cur_app_pid_score != score) { 805 if (cur_app_pid_score != score) {
793 VLOG(3) << "Set OOM score " << score << " for " << *cur; 806 VLOG(3) << "Set OOM score " << score << " for " << *cur;
794 SetOomScoreAdjForApp(cur->app->nspid(), score); 807 SetOomScoreAdjForApp(cur->app()->nspid(), score);
795 } 808 }
796 } else { 809 } else {
797 base::ProcessHandle process_handle = cur->tab->renderer_handle; 810 base::ProcessHandle process_handle = cur->tab()->renderer_handle;
798 // 1. tab_list contains entries for already-discarded tabs. If the PID 811 // 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. 812 // (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 813 // 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 814 // the same process, the process is set to an OOM score based on its "most
802 // important" tab. 815 // important" tab.
803 if (process_handle != 0 && 816 if (process_handle != 0 &&
804 new_map->find(process_handle) == new_map->end()) { 817 new_map->find(process_handle) == new_map->end()) {
805 (*new_map)[process_handle] = score; 818 (*new_map)[process_handle] = score;
806 int process_handle_score = 0; 819 int process_handle_score = 0;
807 { 820 {
808 base::AutoLock oom_score_autolock(oom_score_lock_); 821 base::AutoLock oom_score_autolock(oom_score_lock_);
809 process_handle_score = oom_score_map_[process_handle]; 822 process_handle_score = oom_score_map_[process_handle];
810 } 823 }
811 if (process_handle_score != score) { 824 if (process_handle_score != score) {
812 oom_score_for_tabs.push_back(std::make_pair(process_handle, score)); 825 oom_score_for_tabs.push_back(std::make_pair(process_handle, score));
813 VLOG(3) << "Set OOM score " << score << " for " << *cur; 826 VLOG(3) << "Set OOM score " << score << " for " << *cur;
814 } 827 }
815 } else { 828 } else {
816 continue; // Skip priority increment. 829 continue; // Skip priority increment.
817 } 830 }
818 } 831 }
819 priority += priority_increment; 832 priority += priority_increment;
820 } 833 }
821 834
822 if (oom_score_for_tabs.size()) 835 if (oom_score_for_tabs.size())
823 SetOomScoreAdjForTabs(oom_score_for_tabs); 836 SetOomScoreAdjForTabs(oom_score_for_tabs);
824 } 837 }
825 838
826 } // namespace memory 839 } // 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