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

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: TabManagerDelegate: Better prioritize ARC processes. 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 } 68 }
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 application_id.find(kArcProcessNamePrefix) == 0; 75 return application_id.find(kArcProcessNamePrefix) == 0;
76 } 76 }
77 77
78 bool IsArcWindowInForeground() {
79 auto activation_client = GetActivationClient();
80 return activation_client && IsArcWindow(activation_client->GetActiveWindow());
81 }
82
83 int AppStateToPriority(
84 const arc::mojom::ProcessState& process_state) {
85 // Logic copied from Android:
86 // frameworks/base/core/java/android/app/ActivityManager.java
87 // Note that ProcessState enumerates from most important (lower value) to
88 // least important (higher value), while ProcessPriority enumerates the
89 // opposite.
90 if (process_state >= arc::mojom::ProcessState::HOME) {
91 return ProcessPriority::ANDROID_BACKGROUND;
92 } else if (process_state >= arc::mojom::ProcessState::SERVICE) {
93 return ProcessPriority::ANDROID_SERVICE;
94 } else if (process_state >= arc::mojom::ProcessState::HEAVY_WEIGHT) {
95 return ProcessPriority::ANDROID_CANT_SAVE_STATE;
96 } else if (process_state >= arc::mojom::ProcessState::IMPORTANT_BACKGROUND) {
97 return ProcessPriority::ANDROID_PERCEPTIBLE;
98 } else if (process_state >= arc::mojom::ProcessState::IMPORTANT_FOREGROUND) {
99 return ProcessPriority::ANDROID_VISIBLE;
100 } else if (process_state >= arc::mojom::ProcessState::TOP_SLEEPING) {
101 return ProcessPriority::ANDROID_TOP_SLEEPING;
102 } else if (process_state >= arc::mojom::ProcessState::FOREGROUND_SERVICE) {
103 return ProcessPriority::ANDROID_FOREGROUND_SERVICE;
104 } else if (process_state >= arc::mojom::ProcessState::TOP) {
105 return IsArcWindowInForeground() ?
106 ProcessPriority::ANDROID_TOP :
107 ProcessPriority::ANDROID_TOP_INACTIVE;
108 } else if (process_state >= arc::mojom::ProcessState::PERSISTENT) {
109 return ProcessPriority::ANDROID_PERSISTENT;
110 }
111 return ProcessPriority::ANDROID_NON_EXISTS;
112 }
113
114 int TabStatsToPriority(const TabStats& tab) {
115 if (tab.is_selected)
116 return ProcessPriority::CHROME_SELECTED;
117
118 int priority = 0;
119
120 if (tab.is_app) {
121 priority = ProcessPriority::CHROME_APP;
122 } else if (tab.is_internal_page) {
123 priority = ProcessPriority::CHROME_INTERNAL;
124 } else {
125 priority = ProcessPriority::CHROME_NORMAL;
126 }
127 if (tab.is_pinned)
128 priority |= ProcessPriority::CHROME_PINNED;
129 if (tab.is_media)
130 priority |= ProcessPriority::CHROME_MEDIA;
131 if (tab.has_form_entry)
132 priority |= ProcessPriority::CHROME_CANT_SAVE_STATE;
133
134 return priority;
135 }
136
137 bool IsArcMemoryManagementEnabled() { 78 bool IsArcMemoryManagementEnabled() {
138 return base::FeatureList::IsEnabled(features::kArcMemoryManagement); 79 return base::FeatureList::IsEnabled(features::kArcMemoryManagement);
139 } 80 }
140 81
141 } // namespace 82 } // namespace
142 83
143 std::ostream& operator<<( 84 std::ostream& operator<<(
144 std::ostream& out, const TabManagerDelegate::Candidate& candidate) { 85 std::ostream& out, const TabManagerDelegate::Candidate& candidate) {
145 if (candidate.is_arc_app) { 86 if (candidate.app()) {
146 out << "app " << candidate.app->pid() 87 out << "app " << candidate.app()->pid()
147 << " (" << candidate.app->process_name() << ")"; 88 << " (" << candidate.app()->process_name() << ")"
148 } else { 89 << ", adj " << candidate.app()->adj()
149 out << "tab " << candidate.tab->renderer_handle; 90 << ", lastActivityTime " << candidate.app()->last_activity_time();
91 } else if (candidate.tab()) {
92 out << "tab " << candidate.tab()->renderer_handle;
150 } 93 }
151 out << " with priority " << candidate.priority; 94 out << ", process_type " << candidate.process_type();
152 return out; 95 return out;
153 } 96 }
154 97
155 // Holds the info of a newly focused tab or app window. The focused process is 98 // Holds the info of a newly focused tab or app window. The focused process is
156 // set to highest priority (lowest OOM score), but not immediately. To avoid 99 // set to highest priority (lowest OOM score), but not immediately. To avoid
157 // redundant settings the OOM score adjusting only happens after a timeout. If 100 // redundant settings the OOM score adjusting only happens after a timeout. If
158 // the process loses focus before the timeout, the adjustment is canceled. 101 // the process loses focus before the timeout, the adjustment is canceled.
159 // 102 //
160 // This information might be set on UI thread and looked up on FILE thread. So a 103 // This information might be set on UI thread and looked up on FILE thread. So a
161 // lock is needed to avoid racing. 104 // lock is needed to avoid racing.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 int TabManagerDelegate::MemoryStat::EstimatedMemoryFreedKB( 220 int TabManagerDelegate::MemoryStat::EstimatedMemoryFreedKB(
278 base::ProcessHandle pid) { 221 base::ProcessHandle pid) {
279 std::unique_ptr<base::ProcessMetrics> process_metrics( 222 std::unique_ptr<base::ProcessMetrics> process_metrics(
280 base::ProcessMetrics::CreateProcessMetrics(pid)); 223 base::ProcessMetrics::CreateProcessMetrics(pid));
281 base::WorkingSetKBytes mem_usage; 224 base::WorkingSetKBytes mem_usage;
282 process_metrics->GetWorkingSetKBytes(&mem_usage); 225 process_metrics->GetWorkingSetKBytes(&mem_usage);
283 return mem_usage.priv; 226 return mem_usage.priv;
284 } 227 }
285 228
286 class TabManagerDelegate::UmaReporter { 229 class TabManagerDelegate::UmaReporter {
287 public: 230 public:
288 UmaReporter() 231 UmaReporter()
289 : last_kill_time_(), total_kills_(0) {} 232 : last_kill_time_(), total_kills_(0) {}
290 ~UmaReporter() {} 233 ~UmaReporter() {}
291 void ReportKill(const int memory_freed); 234 void ReportKill(const int memory_freed);
292 235
293 private: 236 private:
294 base::Time last_kill_time_; 237 base::Time last_kill_time_;
295 int total_kills_; 238 int total_kills_;
296 }; 239 };
297 240
298 void TabManagerDelegate::UmaReporter::ReportKill(const int memory_freed) { 241 void TabManagerDelegate::UmaReporter::ReportKill(const int memory_freed) {
299 base::Time now = base::Time::Now(); 242 base::Time now = base::Time::Now();
300 const TimeDelta time_delta = 243 const TimeDelta time_delta =
301 last_kill_time_.is_null() ? 244 last_kill_time_.is_null() ?
302 TimeDelta::FromSeconds(arc::kMaxOomMemoryKillTimeDeltaSecs) : 245 TimeDelta::FromSeconds(arc::kMaxOomMemoryKillTimeDeltaSecs) :
303 (now - last_kill_time_); 246 (now - last_kill_time_);
304 UMA_HISTOGRAM_OOM_KILL_TIME_INTERVAL( 247 UMA_HISTOGRAM_OOM_KILL_TIME_INTERVAL(
305 "Arc.LowMemoryKiller.TimeDelta", time_delta); 248 "Arc.LowMemoryKiller.TimeDelta", time_delta);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 } 340 }
398 VLOG(2) << "Disable LowMemoryKiller"; 341 VLOG(2) << "Disable LowMemoryKiller";
399 arc_process_instance_->DisableLowMemoryKiller(); 342 arc_process_instance_->DisableLowMemoryKiller();
400 } 343 }
401 344
402 void TabManagerDelegate::OnProcessInstanceClosed() { 345 void TabManagerDelegate::OnProcessInstanceClosed() {
403 arc_process_instance_ = nullptr; 346 arc_process_instance_ = nullptr;
404 arc_process_instance_version_ = 0; 347 arc_process_instance_version_ = 0;
405 } 348 }
406 349
350 // TODO(cylee): Remove this function if Android process OOM score settings
351 // is moved back to Android.
352 // For example, negotiate non-overlapping OOM score ranges so Chrome and Android
353 // can set OOM score for processes in their own world.
407 void TabManagerDelegate::OnWindowActivated( 354 void TabManagerDelegate::OnWindowActivated(
408 aura::client::ActivationChangeObserver::ActivationReason reason, 355 aura::client::ActivationChangeObserver::ActivationReason reason,
409 aura::Window* gained_active, 356 aura::Window* gained_active,
410 aura::Window* lost_active) { 357 aura::Window* lost_active) {
411 if (IsArcWindow(gained_active)) { 358 if (IsArcWindow(gained_active)) {
412 // Currently there is no way to know which app is displayed in the ARC 359 // Currently there is no way to know which app is displayed in the ARC
413 // window, so schedule an early adjustment for all processes to reflect 360 // window, so schedule an early adjustment for all processes to reflect
414 // the change. 361 // the change.
415 // Put a dummy FocusedProcess with nspid = kInvalidArcAppNspid for now to 362 // Put a dummy FocusedProcess with nspid = kInvalidArcAppNspid for now to
416 // indicate the focused process is an arc app. 363 // indicate the focused process is an arc app.
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 base::Bind(&TabManagerDelegate::AdjustOomPrioritiesImpl, 537 base::Bind(&TabManagerDelegate::AdjustOomPrioritiesImpl,
591 weak_ptr_factory_.GetWeakPtr(), tab_list))) { 538 weak_ptr_factory_.GetWeakPtr(), tab_list))) {
592 return; 539 return;
593 } 540 }
594 } 541 }
595 // Pass in a dummy list if unable to get ARC processes. 542 // Pass in a dummy list if unable to get ARC processes.
596 AdjustOomPrioritiesImpl(tab_list, std::vector<arc::ArcProcess>()); 543 AdjustOomPrioritiesImpl(tab_list, std::vector<arc::ArcProcess>());
597 } 544 }
598 545
599 // Excludes persistent ARC apps, but still preserves active chrome tabs and 546 // Excludes persistent ARC apps, but still preserves active chrome tabs and
600 // top ARC apps. The latter ones should not be killed by TabManager since 547 // focused ARC apps. The latter ones should not be killed by TabManager here,
601 // we still want to adjust their oom_score_adj. 548 // but we want to adjust their oom_score_adj.
602 // static 549 // static
603 std::vector<TabManagerDelegate::Candidate> 550 std::vector<TabManagerDelegate::Candidate>
604 TabManagerDelegate::GetSortedCandidates( 551 TabManagerDelegate::GetSortedCandidates(
605 const TabStatsList& tab_list, 552 const TabStatsList& tab_list,
606 const std::vector<arc::ArcProcess>& arc_processes) { 553 const std::vector<arc::ArcProcess>& arc_processes) {
607 554
555 static const char kAppLauncherProcessName[] = "org.chromium.arc.applauncher";
556
608 std::vector<Candidate> candidates; 557 std::vector<Candidate> candidates;
609 candidates.reserve(tab_list.size() + arc_processes.size()); 558 candidates.reserve(tab_list.size() + arc_processes.size());
610 559
611 for (const auto& tab : tab_list) { 560 for (const auto& tab : tab_list) {
612 candidates.push_back(Candidate(&tab, TabStatsToPriority(tab))); 561 candidates.push_back(Candidate(&tab));
613 } 562 }
614 563
615 for (const auto& app : arc_processes) { 564 for (const auto& app : arc_processes) {
616 Candidate candidate(&app, AppStateToPriority(app.process_state())); 565 // Persistent an system android processes has negative adj value.
Georges Khalil 2016/06/27 20:15:04 nits: - an -> and - has -> have
cylee1 2016/07/14 19:15:24 Done.
617 // Skip persistent android processes since we should never kill them. 566 // Skip them since they should never be killed here. Also don't ajust
618 // Also don't ajust OOM score so their score remains min oom_score_adj. 567 // OOM score so their score remains min oom_score_adj.
619 if (candidate.priority >= ProcessPriority::ANDROID_PERSISTENT) 568 //
569 // AppLauncher is treated specially in ARC++. For example it is taken
570 // as the dummy foreground app from Android's point of view when the focused
571 // window is not an Android app. We prefer never kill it.
572 if (app.adj() < 0 || app.process_name() == kAppLauncherProcessName)
620 continue; 573 continue;
621 candidates.push_back(candidate); 574 candidates.push_back(Candidate(&app));
622 } 575 }
623 576
624 // Sort candidates according to priority. 577 // Sort candidates according to priority.
625 // TODO(cylee): Missing LRU property. Fix it when apps has the information.
626 std::sort(candidates.begin(), candidates.end()); 578 std::sort(candidates.begin(), candidates.end());
627 579
628 return candidates; 580 return candidates;
629 } 581 }
630 582
631 bool TabManagerDelegate::KillArcProcess(const int nspid) { 583 bool TabManagerDelegate::KillArcProcess(const int nspid) {
632 if (!arc_process_instance_) 584 if (!arc_process_instance_)
633 return false; 585 return false;
634 arc_process_instance_->KillProcess(nspid, "LowMemoryKill"); 586 arc_process_instance_->KillProcess(nspid, "LowMemoryKill");
635 return true; 587 return true;
636 } 588 }
637 589
638 bool TabManagerDelegate::KillTab(int64_t tab_id) { 590 bool TabManagerDelegate::KillTab(int64_t tab_id) {
639 // Check |tab_manager_| is alive before taking tabs into consideration. 591 // Check |tab_manager_| is alive before taking tabs into consideration.
640 return tab_manager_ && 592 return tab_manager_ &&
641 tab_manager_->CanDiscardTab(tab_id) && 593 tab_manager_->CanDiscardTab(tab_id) &&
642 tab_manager_->DiscardTabById(tab_id); 594 tab_manager_->DiscardTabById(tab_id);
643 } 595 }
644 596
645 void TabManagerDelegate::LowMemoryKillImpl( 597 void TabManagerDelegate::LowMemoryKillImpl(
646 const TabStatsList& tab_list, 598 const TabStatsList& tab_list,
647 const std::vector<arc::ArcProcess>& arc_processes) { 599 const std::vector<arc::ArcProcess>& arc_processes) {
648 600
649 VLOG(2) << "LowMemoryKilleImpl"; 601 VLOG(2) << "LowMemoryKilleImpl";
650 std::vector<TabManagerDelegate::Candidate> candidates = 602 const std::vector<TabManagerDelegate::Candidate> candidates =
651 GetSortedCandidates(tab_list, arc_processes); 603 GetSortedCandidates(tab_list, arc_processes);
652 604
653 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB(); 605 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB();
654 for (const auto& entry : candidates) { 606 // Kill processes until the estimated amount of freed memory is sufficient to
607 // bring the system memory back to a normal level.
608 // The list is sorted by importance descendingly, so we go through the list
609 // backwards.
610 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) {
655 VLOG(3) << "Target memory to free: " << target_memory_to_free_kb << " KB"; 611 VLOG(3) << "Target memory to free: " << target_memory_to_free_kb << " KB";
656 // Never kill selected tab or Android foreground app, regardless whether 612 // Never kill selected tab or Android foreground app, regardless whether
657 // they're in the active window. Since the user experience would be bad. 613 // they're in the active window. Since the user experience would be bad.
658 if ((!entry.is_arc_app && 614 ProcessType process_type = it->process_type();
659 entry.priority >= ProcessPriority::CHROME_SELECTED) || 615 if (process_type == ProcessType::VISIBLE_APP ||
660 (entry.is_arc_app && 616 process_type == ProcessType::FOCUSED_APP ||
661 entry.priority >= ProcessPriority::ANDROID_TOP_INACTIVE)) { 617 process_type == ProcessType::FOCUSED_TAB) {
662 VLOG(2) << "Skipped killing " << entry; 618 VLOG(2) << "Skipped killing " << *it;
663 continue; 619 continue;
664 } 620 }
665 if (entry.is_arc_app) { 621 if (it->app()) {
666 int estimated_memory_freed_kb = 622 int estimated_memory_freed_kb =
667 mem_stat_->EstimatedMemoryFreedKB(entry.app->pid()); 623 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid());
668 if (KillArcProcess(entry.app->nspid())) { 624 if (KillArcProcess(it->app()->nspid())) {
669 target_memory_to_free_kb -= estimated_memory_freed_kb; 625 target_memory_to_free_kb -= estimated_memory_freed_kb;
670 uma_->ReportKill(estimated_memory_freed_kb); 626 uma_->ReportKill(estimated_memory_freed_kb);
671 VLOG(2) << "Killed " << entry; 627 VLOG(2) << "Killed " << *it;
672 } 628 }
673 } else { 629 } else {
674 int64_t tab_id = entry.tab->tab_contents_id; 630 int64_t tab_id = it->tab()->tab_contents_id;
675 int estimated_memory_freed_kb = 631 int estimated_memory_freed_kb =
676 mem_stat_->EstimatedMemoryFreedKB(entry.tab->renderer_handle); 632 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle);
677 if (KillTab(tab_id)) { 633 if (KillTab(tab_id)) {
678 target_memory_to_free_kb -= estimated_memory_freed_kb; 634 target_memory_to_free_kb -= estimated_memory_freed_kb;
679 uma_->ReportKill(estimated_memory_freed_kb); 635 uma_->ReportKill(estimated_memory_freed_kb);
680 VLOG(2) << "Killed " << entry; 636 VLOG(2) << "Killed " << *it;
681 } 637 }
682 } 638 }
683 if (target_memory_to_free_kb < 0) 639 if (target_memory_to_free_kb < 0)
684 break; 640 break;
685 } 641 }
686 } 642 }
687 643
688 void TabManagerDelegate::AdjustOomPrioritiesImpl( 644 void TabManagerDelegate::AdjustOomPrioritiesImpl(
689 const TabStatsList& tab_list, 645 const TabStatsList& tab_list,
690 const std::vector<arc::ArcProcess>& arc_processes) { 646 const std::vector<arc::ArcProcess>& arc_processes) {
691 // Least important first. 647 // Least important first.
692 auto candidates = GetSortedCandidates(tab_list, arc_processes); 648 const auto candidates = GetSortedCandidates(tab_list, arc_processes);
693 649
694 // Now we assign priorities based on the sorted list. We're assigning 650 // Now we assign priorities based on the sorted list. We're assigning
695 // priorities in the range of kLowestRendererOomScore to 651 // priorities in the range of kLowestRendererOomScore to
696 // kHighestRendererOomScore (defined in chrome_constants.h). oom_score_adj 652 // kHighestRendererOomScore (defined in chrome_constants.h). oom_score_adj
697 // takes values from -1000 to 1000. Negative values are reserved for system 653 // takes values from -1000 to 1000. Negative values are reserved for system
698 // processes, and we want to give some room below the range we're using to 654 // processes, and we want to give some room below the range we're using to
699 // allow for things that want to be above the renderers in priority, so the 655 // allow for things that want to be above the renderers in priority, so the
700 // defined range gives us some variation in priority without taking up the 656 // defined range gives us some variation in priority without taking up the
701 // whole range. In the end, however, it's a pretty arbitrary range to use. 657 // whole range. In the end, however, it's a pretty arbitrary range to use.
702 // Higher values are more likely to be killed by the OOM killer. 658 // Higher values are more likely to be killed by the OOM killer.
703 659
704 // Break the processes into 2 parts. This is to help lower the chance of 660 // Break the processes into 2 parts. This is to help lower the chance of
705 // altering OOM score for many processes on any small change. 661 // altering OOM score for many processes on any small change.
706 int range_middle = 662 int range_middle =
707 (chrome::kLowestRendererOomScore + chrome::kHighestRendererOomScore) / 2; 663 (chrome::kLowestRendererOomScore + chrome::kHighestRendererOomScore) / 2;
708 664
709 // Find some pivot point. For now processes with priority >= CHROME_INTERNAL 665 // Find some pivot point. For now processes with priority >= CHROME_INTERNAL
710 // are prone to be affected by LRU change. Taking them as "high priority" 666 // are prone to be affected by LRU change. Taking them as "high priority"
711 // processes. 667 // processes.
712 auto lower_priority_part = candidates.rend(); 668 auto lower_priority_part = candidates.end();
713 // Iterate in reverse order since the list is sorted by least importance. 669 for (auto it = candidates.begin(); it != candidates.end(); ++it) {
714 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { 670 if (it->process_type() >= ProcessType::BACKGROUND_APP) {
715 if (it->priority < ProcessPriority::CHROME_INTERNAL) {
716 lower_priority_part = it; 671 lower_priority_part = it;
717 break; 672 break;
718 } 673 }
719 } 674 }
720 675
721 ProcessScoreMap new_map; 676 ProcessScoreMap new_map;
722 677
723 // Higher priority part. 678 // Higher priority part.
724 DistributeOomScoreInRange(candidates.rbegin(), lower_priority_part, 679 DistributeOomScoreInRange(candidates.begin(), lower_priority_part,
725 chrome::kLowestRendererOomScore, range_middle, 680 chrome::kLowestRendererOomScore, range_middle,
726 &new_map); 681 &new_map);
727 // Lower priority part. 682 // Lower priority part.
728 DistributeOomScoreInRange(lower_priority_part, candidates.rend(), 683 DistributeOomScoreInRange(lower_priority_part, candidates.end(),
729 range_middle, chrome::kHighestRendererOomScore, 684 range_middle, chrome::kHighestRendererOomScore,
730 &new_map); 685 &new_map);
731 base::AutoLock oom_score_autolock(oom_score_lock_); 686 base::AutoLock oom_score_autolock(oom_score_lock_);
732 oom_score_map_.swap(new_map); 687 oom_score_map_.swap(new_map);
733 } 688 }
734 689
735 void TabManagerDelegate::SetOomScoreAdjForApp(int nspid, int score) { 690 void TabManagerDelegate::SetOomScoreAdjForApp(int nspid, int score) {
736 if (!arc_process_instance_) 691 if (!arc_process_instance_)
737 return; 692 return;
738 if (arc_process_instance_version_ < 2) { 693 if (arc_process_instance_version_ < 2) {
(...skipping 15 matching lines...) Expand all
754 void TabManagerDelegate::SetOomScoreAdjForTabsOnFileThread( 709 void TabManagerDelegate::SetOomScoreAdjForTabsOnFileThread(
755 const std::vector<std::pair<base::ProcessHandle, int>>& entries) { 710 const std::vector<std::pair<base::ProcessHandle, int>>& entries) {
756 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 711 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
757 for (const auto& entry : entries) { 712 for (const auto& entry : entries) {
758 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore(entry.first, 713 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore(entry.first,
759 entry.second); 714 entry.second);
760 } 715 }
761 } 716 }
762 717
763 void TabManagerDelegate::DistributeOomScoreInRange( 718 void TabManagerDelegate::DistributeOomScoreInRange(
764 std::vector<TabManagerDelegate::Candidate>::reverse_iterator rbegin, 719 std::vector<TabManagerDelegate::Candidate>::const_iterator begin,
765 std::vector<TabManagerDelegate::Candidate>::reverse_iterator rend, 720 std::vector<TabManagerDelegate::Candidate>::const_iterator end,
766 int range_begin, 721 int range_begin,
767 int range_end, 722 int range_end,
768 ProcessScoreMap* new_map) { 723 ProcessScoreMap* new_map) {
769 // OOM score setting for tabs involves file system operation so should be 724 // OOM score setting for tabs involves file system operation so should be
770 // done on file thread. 725 // done on file thread.
771 std::vector<std::pair<base::ProcessHandle, int>> oom_score_for_tabs; 726 std::vector<std::pair<base::ProcessHandle, int>> oom_score_for_tabs;
772 727
773 // Though there might be duplicate process handles, it doesn't matter to 728 // Though there might be duplicate process handles, it doesn't matter to
774 // overestimate the number of processes here since the we don't need to 729 // overestimate the number of processes here since the we don't need to
775 // use up the full range. 730 // use up the full range.
776 int num = (rend - rbegin); 731 int num = (end - begin);
777 const float priority_increment = 732 const float priority_increment =
778 static_cast<float>(range_end - range_begin) / num; 733 static_cast<float>(range_end - range_begin) / num;
779 734
780 float priority = range_begin; 735 float priority = range_begin;
781 for (auto cur = rbegin; cur != rend; ++cur) { 736 for (auto cur = begin; cur != end; ++cur) {
782 int score = static_cast<int>(priority + 0.5f); 737 int score = static_cast<int>(priority + 0.5f);
783 if (cur->is_arc_app) { 738 if (cur->app()) {
784 // Use pid as map keys so it's globally unique. 739 // Use pid as map keys so it's globally unique.
785 (*new_map)[cur->app->pid()] = score; 740 (*new_map)[cur->app()->pid()] = score;
786 int cur_app_pid_score = 0; 741 int cur_app_pid_score = 0;
787 { 742 {
788 base::AutoLock oom_score_autolock(oom_score_lock_); 743 base::AutoLock oom_score_autolock(oom_score_lock_);
789 cur_app_pid_score = oom_score_map_[cur->app->pid()]; 744 cur_app_pid_score = oom_score_map_[cur->app()->pid()];
790 } 745 }
791 if (cur_app_pid_score != score) { 746 if (cur_app_pid_score != score) {
792 VLOG(3) << "Set OOM score " << score << " for " << *cur; 747 VLOG(3) << "Set OOM score " << score << " for " << *cur;
793 SetOomScoreAdjForApp(cur->app->nspid(), score); 748 SetOomScoreAdjForApp(cur->app()->nspid(), score);
794 } 749 }
795 } else { 750 } else {
796 base::ProcessHandle process_handle = cur->tab->renderer_handle; 751 base::ProcessHandle process_handle = cur->tab()->renderer_handle;
797 // 1. tab_list contains entries for already-discarded tabs. If the PID 752 // 1. tab_list contains entries for already-discarded tabs. If the PID
798 // (renderer_handle) is zero, we don't need to adjust the oom_score. 753 // (renderer_handle) is zero, we don't need to adjust the oom_score.
799 // 2. Only add unseen process handle so if there's multiple tab maps to 754 // 2. Only add unseen process handle so if there's multiple tab maps to
800 // the same process, the process is set to an OOM score based on its "most 755 // the same process, the process is set to an OOM score based on its "most
801 // important" tab. 756 // important" tab.
802 if (process_handle != 0 && 757 if (process_handle != 0 &&
803 new_map->find(process_handle) == new_map->end()) { 758 new_map->find(process_handle) == new_map->end()) {
804 (*new_map)[process_handle] = score; 759 (*new_map)[process_handle] = score;
805 int process_handle_score = 0; 760 int process_handle_score = 0;
806 { 761 {
807 base::AutoLock oom_score_autolock(oom_score_lock_); 762 base::AutoLock oom_score_autolock(oom_score_lock_);
808 process_handle_score = oom_score_map_[process_handle]; 763 process_handle_score = oom_score_map_[process_handle];
809 } 764 }
810 if (process_handle_score != score) { 765 if (process_handle_score != score) {
811 oom_score_for_tabs.push_back(std::make_pair(process_handle, score)); 766 oom_score_for_tabs.push_back(std::make_pair(process_handle, score));
812 VLOG(3) << "Set OOM score " << score << " for " << *cur; 767 VLOG(3) << "Set OOM score " << score << " for " << *cur;
813 } 768 }
814 } else { 769 } else {
815 continue; // Skip priority increment. 770 continue; // Skip priority increment.
816 } 771 }
817 } 772 }
818 priority += priority_increment; 773 priority += priority_increment;
819 } 774 }
820 775
821 if (oom_score_for_tabs.size()) 776 if (oom_score_for_tabs.size())
822 SetOomScoreAdjForTabs(oom_score_for_tabs); 777 SetOomScoreAdjForTabs(oom_score_for_tabs);
823 } 778 }
824 779
825 } // namespace memory 780 } // namespace memory
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698