| OLD | NEW |
| 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 <math.h> | 7 #include <math.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 default: | 114 default: |
| 115 return os << "NOT_IMPLEMENTED_ERROR"; | 115 return os << "NOT_IMPLEMENTED_ERROR"; |
| 116 } | 116 } |
| 117 return os; | 117 return os; |
| 118 } | 118 } |
| 119 | 119 |
| 120 // TabManagerDelegate::Candidate implementation. | 120 // TabManagerDelegate::Candidate implementation. |
| 121 std::ostream& operator<<( | 121 std::ostream& operator<<( |
| 122 std::ostream& out, const TabManagerDelegate::Candidate& candidate) { | 122 std::ostream& out, const TabManagerDelegate::Candidate& candidate) { |
| 123 if (candidate.app()) { | 123 if (candidate.app()) { |
| 124 out << "app " << candidate.app()->pid() << " (" | 124 out << "app " << *candidate.app(); |
| 125 << candidate.app()->process_name() << ")" | |
| 126 << ", process_state " << candidate.app()->process_state() | |
| 127 << ", is_focused " << candidate.app()->is_focused() | |
| 128 << ", lastActivityTime " << candidate.app()->last_activity_time(); | |
| 129 } else if (candidate.tab()) { | 125 } else if (candidate.tab()) { |
| 130 out << "tab " << candidate.tab()->renderer_handle; | 126 const TabStats* const& tab = candidate.tab(); |
| 127 out << "tab " << tab->title << ", renderer_handle: " << tab->renderer_handle |
| 128 << ", oom_score: " << tab->oom_score |
| 129 << ", is_discarded: " << tab->is_discarded |
| 130 << ", discard_count: " << tab->discard_count |
| 131 << ", last_active: " << tab->last_active; |
| 131 } | 132 } |
| 132 out << ", process_type " << candidate.process_type(); | 133 out << ", process_type " << candidate.process_type(); |
| 133 return out; | 134 return out; |
| 134 } | 135 } |
| 135 | 136 |
| 136 TabManagerDelegate::Candidate& TabManagerDelegate::Candidate::operator=( | 137 TabManagerDelegate::Candidate& TabManagerDelegate::Candidate::operator=( |
| 137 TabManagerDelegate::Candidate&& other) { | 138 TabManagerDelegate::Candidate&& other) { |
| 138 tab_ = other.tab_; | 139 tab_ = other.tab_; |
| 139 app_ = other.app_; | 140 app_ = other.app_; |
| 140 process_type_ = other.process_type_; | 141 process_type_ = other.process_type_; |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 const std::vector<arc::ArcProcess>& arc_processes) { | 585 const std::vector<arc::ArcProcess>& arc_processes) { |
| 585 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 586 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 586 VLOG(2) << "LowMemoryKillImpl"; | 587 VLOG(2) << "LowMemoryKillImpl"; |
| 587 | 588 |
| 588 const std::vector<TabManagerDelegate::Candidate> candidates = | 589 const std::vector<TabManagerDelegate::Candidate> candidates = |
| 589 GetSortedCandidates(tab_list, arc_processes); | 590 GetSortedCandidates(tab_list, arc_processes); |
| 590 | 591 |
| 591 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB(); | 592 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB(); |
| 592 const TimeTicks now = TimeTicks::Now(); | 593 const TimeTicks now = TimeTicks::Now(); |
| 593 | 594 |
| 595 MEMORY_LOG(ERROR) << "List of low memory kill candidates " |
| 596 "(sorted from low priority to high priority):"; |
| 597 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { |
| 598 MEMORY_LOG(ERROR) << *it; |
| 599 } |
| 594 // Kill processes until the estimated amount of freed memory is sufficient to | 600 // Kill processes until the estimated amount of freed memory is sufficient to |
| 595 // bring the system memory back to a normal level. | 601 // bring the system memory back to a normal level. |
| 596 // The list is sorted by descending importance, so we go through the list | 602 // The list is sorted by descending importance, so we go through the list |
| 597 // backwards. | 603 // backwards. |
| 598 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { | 604 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { |
| 599 MEMORY_LOG(ERROR) << "Target memory to free: " << target_memory_to_free_kb | 605 MEMORY_LOG(ERROR) << "Target memory to free: " << target_memory_to_free_kb |
| 600 << " KB"; | 606 << " KB"; |
| 601 if (target_memory_to_free_kb <= 0) | 607 if (target_memory_to_free_kb <= 0) |
| 602 break; | 608 break; |
| 603 // Never kill selected tab, foreground app, and important apps regardless of | 609 // Never kill selected tab, foreground app, and important apps regardless of |
| 604 // whether they're in the active window. Since the user experience would be | 610 // whether they're in the active window. Since the user experience would be |
| 605 // bad. | 611 // bad. |
| 606 ProcessType process_type = it->process_type(); | 612 ProcessType process_type = it->process_type(); |
| 607 if (process_type <= ProcessType::IMPORTANT_APP) { | 613 if (process_type <= ProcessType::IMPORTANT_APP) { |
| 608 MEMORY_LOG(ERROR) << "Skipped killing " << *it; | 614 MEMORY_LOG(ERROR) << "Skipped killing " << it->app()->process_name(); |
| 609 continue; | 615 continue; |
| 610 } | 616 } |
| 611 if (it->app()) { | 617 if (it->app()) { |
| 612 if (IsRecentlyKilledArcProcess(it->app()->process_name(), now)) { | 618 if (IsRecentlyKilledArcProcess(it->app()->process_name(), now)) { |
| 613 MEMORY_LOG(ERROR) << "Avoided killing " << *it << " too often"; | 619 MEMORY_LOG(ERROR) << "Avoided killing " << it->app()->process_name() |
| 620 << " too often"; |
| 614 continue; | 621 continue; |
| 615 } | 622 } |
| 616 int estimated_memory_freed_kb = | 623 int estimated_memory_freed_kb = |
| 617 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid()); | 624 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid()); |
| 618 if (KillArcProcess(it->app()->nspid())) { | 625 if (KillArcProcess(it->app()->nspid())) { |
| 619 recently_killed_arc_processes_[it->app()->process_name()] = now; | 626 recently_killed_arc_processes_[it->app()->process_name()] = now; |
| 620 target_memory_to_free_kb -= estimated_memory_freed_kb; | 627 target_memory_to_free_kb -= estimated_memory_freed_kb; |
| 621 MemoryKillsMonitor::LogLowMemoryKill("APP", estimated_memory_freed_kb); | 628 MemoryKillsMonitor::LogLowMemoryKill("APP", estimated_memory_freed_kb); |
| 622 MEMORY_LOG(ERROR) << "Killed " << *it << ", estimated " | 629 MEMORY_LOG(ERROR) << "Killed app " << it->app()->process_name() << " (" |
| 623 << estimated_memory_freed_kb << " KB freed"; | 630 << it->app()->pid() << ")" |
| 631 << ", estimated " << estimated_memory_freed_kb |
| 632 << " KB freed"; |
| 624 } else { | 633 } else { |
| 625 MEMORY_LOG(ERROR) << "Failed to kill " << *it; | 634 MEMORY_LOG(ERROR) << "Failed to kill " << it->app()->process_name(); |
| 626 } | 635 } |
| 627 } else { | 636 } else { |
| 628 int64_t tab_id = it->tab()->tab_contents_id; | 637 int64_t tab_id = it->tab()->tab_contents_id; |
| 629 // The estimation is problematic since multiple tabs may share the same | 638 // The estimation is problematic since multiple tabs may share the same |
| 630 // process, while the calculation counts memory used by the whole process. | 639 // process, while the calculation counts memory used by the whole process. |
| 631 // So |estimated_memory_freed_kb| is an over-estimation. | 640 // So |estimated_memory_freed_kb| is an over-estimation. |
| 632 int estimated_memory_freed_kb = | 641 int estimated_memory_freed_kb = |
| 633 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle); | 642 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle); |
| 634 if (KillTab(tab_id)) { | 643 if (KillTab(tab_id)) { |
| 635 target_memory_to_free_kb -= estimated_memory_freed_kb; | 644 target_memory_to_free_kb -= estimated_memory_freed_kb; |
| 636 MemoryKillsMonitor::LogLowMemoryKill("TAB", estimated_memory_freed_kb); | 645 MemoryKillsMonitor::LogLowMemoryKill("TAB", estimated_memory_freed_kb); |
| 637 MEMORY_LOG(ERROR) << "Killed " << *it << ", estimated " | 646 MEMORY_LOG(ERROR) << "Killed tab " << it->tab()->title << " (" |
| 647 << it->tab()->renderer_handle << "), estimated " |
| 638 << estimated_memory_freed_kb << " KB freed"; | 648 << estimated_memory_freed_kb << " KB freed"; |
| 639 } | 649 } |
| 640 } | 650 } |
| 641 } | 651 } |
| 642 if (target_memory_to_free_kb > 0) { | 652 if (target_memory_to_free_kb > 0) { |
| 643 MEMORY_LOG(ERROR) | 653 MEMORY_LOG(ERROR) |
| 644 << "Unable to kill enough candidates to meet target_memory_to_free_kb "; | 654 << "Unable to kill enough candidates to meet target_memory_to_free_kb "; |
| 645 } | 655 } |
| 646 } | 656 } |
| 647 | 657 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 priority += priority_increment; | 780 priority += priority_increment; |
| 771 } | 781 } |
| 772 | 782 |
| 773 if (oom_scores_to_change.size()) { | 783 if (oom_scores_to_change.size()) { |
| 774 GetDebugDaemonClient()->SetOomScoreAdj( | 784 GetDebugDaemonClient()->SetOomScoreAdj( |
| 775 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); | 785 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); |
| 776 } | 786 } |
| 777 } | 787 } |
| 778 | 788 |
| 779 } // namespace memory | 789 } // namespace memory |
| OLD | NEW |