| 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 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 void TabManagerDelegate::LowMemoryKillImpl( | 581 void TabManagerDelegate::LowMemoryKillImpl( |
| 582 const TabStatsList& tab_list, | 582 const TabStatsList& tab_list, |
| 583 const std::vector<arc::ArcProcess>& arc_processes) { | 583 const std::vector<arc::ArcProcess>& arc_processes) { |
| 584 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 584 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 585 VLOG(2) << "LowMemoryKillImpl"; | 585 VLOG(2) << "LowMemoryKillImpl"; |
| 586 | 586 |
| 587 const std::vector<TabManagerDelegate::Candidate> candidates = | 587 const std::vector<TabManagerDelegate::Candidate> candidates = |
| 588 GetSortedCandidates(tab_list, arc_processes); | 588 GetSortedCandidates(tab_list, arc_processes); |
| 589 | 589 |
| 590 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB(); | 590 int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB(); |
| 591 bool killed_candidate = false; | |
| 592 | 591 |
| 593 // Kill processes until the estimated amount of freed memory is sufficient to | 592 // Kill processes until the estimated amount of freed memory is sufficient to |
| 594 // bring the system memory back to a normal level. | 593 // bring the system memory back to a normal level. |
| 595 // The list is sorted by descending importance, so we go through the list | 594 // The list is sorted by descending importance, so we go through the list |
| 596 // backwards. | 595 // backwards. |
| 597 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { | 596 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { |
| 598 VLOG(3) << "Target memory to free: " << target_memory_to_free_kb << " KB"; | 597 MEMORY_LOG(ERROR) << "Target memory to free: " << target_memory_to_free_kb |
| 598 << " KB"; |
| 599 if (target_memory_to_free_kb <= 0) |
| 600 break; |
| 599 // Never kill selected tab or Android foreground app, regardless whether | 601 // Never kill selected tab or Android foreground app, regardless whether |
| 600 // they're in the active window. Since the user experience would be bad. | 602 // they're in the active window. Since the user experience would be bad. |
| 601 ProcessType process_type = it->process_type(); | 603 ProcessType process_type = it->process_type(); |
| 602 if (process_type == ProcessType::VISIBLE_APP || | 604 if (process_type == ProcessType::VISIBLE_APP || |
| 603 process_type == ProcessType::FOCUSED_APP || | 605 process_type == ProcessType::FOCUSED_APP || |
| 604 process_type == ProcessType::FOCUSED_TAB) { | 606 process_type == ProcessType::FOCUSED_TAB) { |
| 605 VLOG(2) << "Skipped killing " << *it; | 607 MEMORY_LOG(ERROR) << "Skipped killing " << *it; |
| 606 continue; | 608 continue; |
| 607 } | 609 } |
| 608 if (it->app()) { | 610 if (it->app()) { |
| 609 int estimated_memory_freed_kb = | 611 int estimated_memory_freed_kb = |
| 610 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid()); | 612 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid()); |
| 611 if (KillArcProcess(it->app()->nspid())) { | 613 if (KillArcProcess(it->app()->nspid())) { |
| 612 target_memory_to_free_kb -= estimated_memory_freed_kb; | 614 target_memory_to_free_kb -= estimated_memory_freed_kb; |
| 613 MemoryKillsMonitor::LogLowMemoryKill("APP", estimated_memory_freed_kb); | 615 MemoryKillsMonitor::LogLowMemoryKill("APP", estimated_memory_freed_kb); |
| 614 MEMORY_LOG(ERROR) << "Killed " << *it << ", estimated " | 616 MEMORY_LOG(ERROR) << "Killed " << *it << ", estimated " |
| 615 << estimated_memory_freed_kb << " KB freed"; | 617 << estimated_memory_freed_kb << " KB freed"; |
| 616 killed_candidate = true; | 618 } else { |
| 619 MEMORY_LOG(ERROR) << "Failed to kill " << *it; |
| 617 } | 620 } |
| 618 } else { | 621 } else { |
| 619 int64_t tab_id = it->tab()->tab_contents_id; | 622 int64_t tab_id = it->tab()->tab_contents_id; |
| 620 // The estimation is problematic since multiple tabs may share the same | 623 // The estimation is problematic since multiple tabs may share the same |
| 621 // process, while the calculation counts memory used by the whole process. | 624 // process, while the calculation counts memory used by the whole process. |
| 622 // So |estimated_memory_freed_kb| is an over-estimation. | 625 // So |estimated_memory_freed_kb| is an over-estimation. |
| 623 int estimated_memory_freed_kb = | 626 int estimated_memory_freed_kb = |
| 624 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle); | 627 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle); |
| 625 if (KillTab(tab_id)) { | 628 if (KillTab(tab_id)) { |
| 626 target_memory_to_free_kb -= estimated_memory_freed_kb; | 629 target_memory_to_free_kb -= estimated_memory_freed_kb; |
| 627 MemoryKillsMonitor::LogLowMemoryKill("TAB", estimated_memory_freed_kb); | 630 MemoryKillsMonitor::LogLowMemoryKill("TAB", estimated_memory_freed_kb); |
| 628 MEMORY_LOG(ERROR) << "Killed " << *it << ", estimated " | 631 MEMORY_LOG(ERROR) << "Killed " << *it << ", estimated " |
| 629 << estimated_memory_freed_kb << " KB freed"; | 632 << estimated_memory_freed_kb << " KB freed"; |
| 630 killed_candidate = true; | 633 } else { |
| 634 MEMORY_LOG(ERROR) << "Failed to kill " << *it; |
| 631 } | 635 } |
| 632 } | 636 } |
| 633 if (target_memory_to_free_kb < 0) | |
| 634 break; | |
| 635 } | 637 } |
| 636 if (!killed_candidate) { | 638 if (target_memory_to_free_kb > 0) { |
| 637 MEMORY_LOG(ERROR) << "Low memory: Unable to kill any candidates. " | 639 MEMORY_LOG(ERROR) |
| 638 << "Attempted to free " << target_memory_to_free_kb | 640 << "Unable to kill enough candidates to meet target_memory_to_free_kb "; |
| 639 << " KB"; | |
| 640 } | 641 } |
| 641 } | 642 } |
| 642 | 643 |
| 643 void TabManagerDelegate::AdjustOomPrioritiesImpl( | 644 void TabManagerDelegate::AdjustOomPrioritiesImpl( |
| 644 const TabStatsList& tab_list, | 645 const TabStatsList& tab_list, |
| 645 const std::vector<arc::ArcProcess>& arc_processes) { | 646 const std::vector<arc::ArcProcess>& arc_processes) { |
| 646 // Least important first. | 647 // Least important first. |
| 647 const auto candidates = GetSortedCandidates(tab_list, arc_processes); | 648 const auto candidates = GetSortedCandidates(tab_list, arc_processes); |
| 648 | 649 |
| 649 // 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 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 } | 736 } |
| 736 priority += priority_increment; | 737 priority += priority_increment; |
| 737 } | 738 } |
| 738 | 739 |
| 739 if (oom_scores_to_change.size()) | 740 if (oom_scores_to_change.size()) |
| 740 GetDebugDaemonClient()->SetOomScoreAdj( | 741 GetDebugDaemonClient()->SetOomScoreAdj( |
| 741 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); | 742 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); |
| 742 } | 743 } |
| 743 | 744 |
| 744 } // namespace memory | 745 } // namespace memory |
| OLD | NEW |