| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 default: | 107 default: |
| 108 return os << "NOT_IMPLEMENTED_ERROR"; | 108 return os << "NOT_IMPLEMENTED_ERROR"; |
| 109 } | 109 } |
| 110 return os; | 110 return os; |
| 111 } | 111 } |
| 112 | 112 |
| 113 // TabManagerDelegate::Candidate implementation. | 113 // TabManagerDelegate::Candidate implementation. |
| 114 std::ostream& operator<<( | 114 std::ostream& operator<<( |
| 115 std::ostream& out, const TabManagerDelegate::Candidate& candidate) { | 115 std::ostream& out, const TabManagerDelegate::Candidate& candidate) { |
| 116 if (candidate.app()) { | 116 if (candidate.app()) { |
| 117 out << "app " << candidate.app()->pid() << " (" | 117 out << "app " << *candidate.app(); |
| 118 << candidate.app()->process_name() << ")" | |
| 119 << ", process_state " << candidate.app()->process_state() | |
| 120 << ", is_focused " << candidate.app()->is_focused() | |
| 121 << ", lastActivityTime " << candidate.app()->last_activity_time(); | |
| 122 } else if (candidate.tab()) { | 118 } else if (candidate.tab()) { |
| 123 out << "tab " << candidate.tab()->renderer_handle; | 119 const TabStats* const& tab = candidate.tab(); |
| 120 out << "tab " << tab->title << ", renderer_handle: " << tab->renderer_handle |
| 121 << ", oom_score: " << tab->oom_score |
| 122 << ", is_discarded: " << tab->is_discarded |
| 123 << ", discard_count: " << tab->discard_count |
| 124 << ", last_active: " << tab->last_active; |
| 124 } | 125 } |
| 125 out << ", process_type " << candidate.process_type(); | 126 out << ", process_type " << candidate.process_type(); |
| 126 return out; | 127 return out; |
| 127 } | 128 } |
| 128 | 129 |
| 129 TabManagerDelegate::Candidate& TabManagerDelegate::Candidate::operator=( | 130 TabManagerDelegate::Candidate& TabManagerDelegate::Candidate::operator=( |
| 130 TabManagerDelegate::Candidate&& other) { | 131 TabManagerDelegate::Candidate&& other) { |
| 131 tab_ = other.tab_; | 132 tab_ = other.tab_; |
| 132 app_ = other.app_; | 133 app_ = other.app_; |
| 133 process_type_ = other.process_type_; | 134 process_type_ = other.process_type_; |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 const std::vector<arc::ArcProcess>& arc_processes) { | 595 const std::vector<arc::ArcProcess>& arc_processes) { |
| 595 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 596 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 596 VLOG(2) << "LowMemoryKillImpl"; | 597 VLOG(2) << "LowMemoryKillImpl"; |
| 597 | 598 |
| 598 const std::vector<TabManagerDelegate::Candidate> candidates = | 599 const std::vector<TabManagerDelegate::Candidate> candidates = |
| 599 GetSortedCandidates(tab_list, arc_processes); | 600 GetSortedCandidates(tab_list, arc_processes); |
| 600 | 601 |
| 601 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB(); | 602 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB(); |
| 602 const TimeTicks now = TimeTicks::Now(); | 603 const TimeTicks now = TimeTicks::Now(); |
| 603 | 604 |
| 605 MEMORY_LOG(ERROR) << "List of low memory kill candidates " |
| 606 "(sorted from low priority to high priority):"; |
| 607 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { |
| 608 MEMORY_LOG(ERROR) << *it; |
| 609 } |
| 604 // Kill processes until the estimated amount of freed memory is sufficient to | 610 // Kill processes until the estimated amount of freed memory is sufficient to |
| 605 // bring the system memory back to a normal level. | 611 // bring the system memory back to a normal level. |
| 606 // The list is sorted by descending importance, so we go through the list | 612 // The list is sorted by descending importance, so we go through the list |
| 607 // backwards. | 613 // backwards. |
| 608 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { | 614 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { |
| 609 MEMORY_LOG(ERROR) << "Target memory to free: " << target_memory_to_free_kb | 615 MEMORY_LOG(ERROR) << "Target memory to free: " << target_memory_to_free_kb |
| 610 << " KB"; | 616 << " KB"; |
| 611 if (target_memory_to_free_kb <= 0) | 617 if (target_memory_to_free_kb <= 0) |
| 612 break; | 618 break; |
| 613 // Never kill selected tab or Android foreground app, regardless whether | 619 // Never kill selected tab or Android foreground app, regardless whether |
| 614 // they're in the active window. Since the user experience would be bad. | 620 // they're in the active window. Since the user experience would be bad. |
| 615 ProcessType process_type = it->process_type(); | 621 ProcessType process_type = it->process_type(); |
| 616 if (process_type == ProcessType::VISIBLE_APP || | 622 if (process_type == ProcessType::VISIBLE_APP || |
| 617 process_type == ProcessType::FOCUSED_APP || | 623 process_type == ProcessType::FOCUSED_APP || |
| 618 process_type == ProcessType::FOCUSED_TAB) { | 624 process_type == ProcessType::FOCUSED_TAB) { |
| 619 MEMORY_LOG(ERROR) << "Skipped killing " << *it; | 625 MEMORY_LOG(ERROR) << "Skipped killing " << it->app()->process_name(); |
| 620 continue; | 626 continue; |
| 621 } | 627 } |
| 622 if (it->app()) { | 628 if (it->app()) { |
| 623 if (IsRecentlyKilledArcProcess(it->app()->process_name(), now)) { | 629 if (IsRecentlyKilledArcProcess(it->app()->process_name(), now)) { |
| 624 MEMORY_LOG(ERROR) << "Avoided killing " << *it << " too often"; | 630 MEMORY_LOG(ERROR) << "Avoided killing " << it->app()->process_name() |
| 631 << " too often"; |
| 625 continue; | 632 continue; |
| 626 } | 633 } |
| 627 int estimated_memory_freed_kb = | 634 int estimated_memory_freed_kb = |
| 628 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid()); | 635 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid()); |
| 629 if (KillArcProcess(it->app()->nspid())) { | 636 if (KillArcProcess(it->app()->nspid())) { |
| 630 recently_killed_arc_processes_[it->app()->process_name()] = now; | 637 recently_killed_arc_processes_[it->app()->process_name()] = now; |
| 631 target_memory_to_free_kb -= estimated_memory_freed_kb; | 638 target_memory_to_free_kb -= estimated_memory_freed_kb; |
| 632 MemoryKillsMonitor::LogLowMemoryKill("APP", estimated_memory_freed_kb); | 639 MemoryKillsMonitor::LogLowMemoryKill("APP", estimated_memory_freed_kb); |
| 633 MEMORY_LOG(ERROR) << "Killed " << *it << ", estimated " | 640 MEMORY_LOG(ERROR) << "Killed app " << it->app()->process_name() << " (" |
| 634 << estimated_memory_freed_kb << " KB freed"; | 641 << it->app()->pid() << ")" |
| 642 << ", estimated " << estimated_memory_freed_kb |
| 643 << " KB freed"; |
| 635 } else { | 644 } else { |
| 636 MEMORY_LOG(ERROR) << "Failed to kill " << *it; | 645 MEMORY_LOG(ERROR) << "Failed to kill " << it->app()->process_name(); |
| 637 } | 646 } |
| 638 } else { | 647 } else { |
| 639 int64_t tab_id = it->tab()->tab_contents_id; | 648 int64_t tab_id = it->tab()->tab_contents_id; |
| 640 // The estimation is problematic since multiple tabs may share the same | 649 // The estimation is problematic since multiple tabs may share the same |
| 641 // process, while the calculation counts memory used by the whole process. | 650 // process, while the calculation counts memory used by the whole process. |
| 642 // So |estimated_memory_freed_kb| is an over-estimation. | 651 // So |estimated_memory_freed_kb| is an over-estimation. |
| 643 int estimated_memory_freed_kb = | 652 int estimated_memory_freed_kb = |
| 644 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle); | 653 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle); |
| 645 if (KillTab(tab_id)) { | 654 if (KillTab(tab_id)) { |
| 646 target_memory_to_free_kb -= estimated_memory_freed_kb; | 655 target_memory_to_free_kb -= estimated_memory_freed_kb; |
| 647 MemoryKillsMonitor::LogLowMemoryKill("TAB", estimated_memory_freed_kb); | 656 MemoryKillsMonitor::LogLowMemoryKill("TAB", estimated_memory_freed_kb); |
| 648 MEMORY_LOG(ERROR) << "Killed " << *it << ", estimated " | 657 MEMORY_LOG(ERROR) << "Killed tab " << it->tab()->title << " (" |
| 658 << it->tab()->renderer_handle << "), estimated " |
| 649 << estimated_memory_freed_kb << " KB freed"; | 659 << estimated_memory_freed_kb << " KB freed"; |
| 650 } | 660 } |
| 651 } | 661 } |
| 652 } | 662 } |
| 653 if (target_memory_to_free_kb > 0) { | 663 if (target_memory_to_free_kb > 0) { |
| 654 MEMORY_LOG(ERROR) | 664 MEMORY_LOG(ERROR) |
| 655 << "Unable to kill enough candidates to meet target_memory_to_free_kb "; | 665 << "Unable to kill enough candidates to meet target_memory_to_free_kb "; |
| 656 } | 666 } |
| 657 } | 667 } |
| 658 | 668 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 } | 761 } |
| 752 priority += priority_increment; | 762 priority += priority_increment; |
| 753 } | 763 } |
| 754 | 764 |
| 755 if (oom_scores_to_change.size()) | 765 if (oom_scores_to_change.size()) |
| 756 GetDebugDaemonClient()->SetOomScoreAdj( | 766 GetDebugDaemonClient()->SetOomScoreAdj( |
| 757 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); | 767 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); |
| 758 } | 768 } |
| 759 | 769 |
| 760 } // namespace memory | 770 } // namespace memory |
| OLD | NEW |