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

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