Chromium Code Reviews| 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 <stdint.h> | 8 #include <stdint.h> |
| 8 | 9 |
| 9 #include <algorithm> | 10 #include <algorithm> |
| 10 #include <map> | 11 #include <map> |
| 11 #include <vector> | 12 #include <vector> |
| 12 | 13 |
| 13 #include "ash/shell.h" | 14 #include "ash/shell.h" |
| 14 #include "base/bind.h" | 15 #include "base/bind.h" |
| 15 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 16 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 29 #include "chrome/browser/memory/memory_kills_monitor.h" | 30 #include "chrome/browser/memory/memory_kills_monitor.h" |
| 30 #include "chrome/browser/memory/tab_stats.h" | 31 #include "chrome/browser/memory/tab_stats.h" |
| 31 #include "chrome/browser/ui/browser.h" | 32 #include "chrome/browser/ui/browser.h" |
| 32 #include "chrome/browser/ui/browser_list.h" | 33 #include "chrome/browser/ui/browser_list.h" |
| 33 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 34 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 34 #include "chrome/common/chrome_constants.h" | 35 #include "chrome/common/chrome_constants.h" |
| 35 #include "chrome/common/chrome_features.h" | 36 #include "chrome/common/chrome_features.h" |
| 36 #include "chromeos/dbus/dbus_thread_manager.h" | 37 #include "chromeos/dbus/dbus_thread_manager.h" |
| 37 #include "components/arc/arc_bridge_service.h" | 38 #include "components/arc/arc_bridge_service.h" |
| 38 #include "components/arc/arc_service_manager.h" | 39 #include "components/arc/arc_service_manager.h" |
| 39 #include "components/arc/common/process.mojom.h" | |
| 40 #include "components/device_event_log/device_event_log.h" | 40 #include "components/device_event_log/device_event_log.h" |
| 41 #include "components/exo/shell_surface.h" | 41 #include "components/exo/shell_surface.h" |
| 42 #include "content/public/browser/browser_thread.h" | 42 #include "content/public/browser/browser_thread.h" |
| 43 #include "content/public/browser/notification_service.h" | 43 #include "content/public/browser/notification_service.h" |
| 44 #include "content/public/browser/notification_types.h" | 44 #include "content/public/browser/notification_types.h" |
| 45 #include "content/public/browser/render_process_host.h" | 45 #include "content/public/browser/render_process_host.h" |
| 46 #include "content/public/browser/render_widget_host.h" | 46 #include "content/public/browser/render_widget_host.h" |
| 47 #include "content/public/browser/zygote_host_linux.h" | 47 #include "content/public/browser/zygote_host_linux.h" |
| 48 #include "ui/aura/window.h" | 48 #include "ui/aura/window.h" |
| 49 #include "ui/wm/public/activation_client.h" | 49 #include "ui/wm/public/activation_client.h" |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 79 return base::StartsWith(application_id, kArcProcessNamePrefix, | 79 return base::StartsWith(application_id, kArcProcessNamePrefix, |
| 80 base::CompareCase::SENSITIVE); | 80 base::CompareCase::SENSITIVE); |
| 81 } | 81 } |
| 82 | 82 |
| 83 bool IsArcMemoryManagementEnabled() { | 83 bool IsArcMemoryManagementEnabled() { |
| 84 return base::FeatureList::IsEnabled(features::kArcMemoryManagement); | 84 return base::FeatureList::IsEnabled(features::kArcMemoryManagement); |
| 85 } | 85 } |
| 86 | 86 |
| 87 void OnSetOomScoreAdj(bool success, const std::string& output) { | 87 void OnSetOomScoreAdj(bool success, const std::string& output) { |
| 88 VLOG(2) << "OnSetOomScoreAdj " << success << " " << output; | 88 VLOG(2) << "OnSetOomScoreAdj " << success << " " << output; |
| 89 if (!success || output != "") | 89 if (!success) |
| 90 LOG(WARNING) << "Set OOM score error: " << output; | 90 LOG(ERROR) << "Set OOM score error: " << output; |
| 91 else if (!output.empty()) | |
| 92 LOG(WARNING) << "Set OOM score: " << output; | |
| 91 } | 93 } |
| 92 | 94 |
| 93 } // namespace | 95 } // namespace |
| 94 | 96 |
| 97 // static | |
| 98 const int TabManagerDelegate::kLowestOomScore = -1000; | |
| 99 | |
| 95 std::ostream& operator<<(std::ostream& os, const ProcessType& type) { | 100 std::ostream& operator<<(std::ostream& os, const ProcessType& type) { |
| 96 switch (type) { | 101 switch (type) { |
| 97 case ProcessType::FOCUSED_TAB: | 102 case ProcessType::FOCUSED_TAB: |
| 98 return os << "FOCUSED_TAB"; | 103 return os << "FOCUSED_TAB"; |
| 99 case ProcessType::FOCUSED_APP: | 104 case ProcessType::FOCUSED_APP: |
| 100 return os << "FOCUSED_APP"; | 105 return os << "FOCUSED_APP"; |
| 101 case ProcessType::VISIBLE_APP: | 106 case ProcessType::IMPORTANT_APP: |
| 102 return os << "VISIBLE_APP"; | 107 return os << "IMPORTANT_APP"; |
| 103 case ProcessType::BACKGROUND_TAB: | 108 case ProcessType::BACKGROUND_TAB: |
| 104 return os << "BACKGROUND_TAB"; | 109 return os << "BACKGROUND_TAB"; |
| 105 case ProcessType::BACKGROUND_APP: | 110 case ProcessType::BACKGROUND_APP: |
| 106 return os << "BACKGROUND_APP"; | 111 return os << "BACKGROUND_APP"; |
| 107 case ProcessType::UNKNOWN_TYPE: | 112 case ProcessType::UNKNOWN_TYPE: |
| 108 return os << "UNKNOWN_TYPE"; | 113 return os << "UNKNOWN_TYPE"; |
| 109 default: | 114 default: |
| 110 return os << "NOT_IMPLEMENTED_ERROR"; | 115 return os << "NOT_IMPLEMENTED_ERROR"; |
| 111 } | 116 } |
| 112 return os; | 117 return os; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 // apps. | 153 // apps. |
| 149 NOTREACHED() << "Undefined comparison between apps and tabs: process_type=" | 154 NOTREACHED() << "Undefined comparison between apps and tabs: process_type=" |
| 150 << process_type(); | 155 << process_type(); |
| 151 return app(); | 156 return app(); |
| 152 } | 157 } |
| 153 | 158 |
| 154 ProcessType TabManagerDelegate::Candidate::GetProcessTypeInternal() const { | 159 ProcessType TabManagerDelegate::Candidate::GetProcessTypeInternal() const { |
| 155 if (app()) { | 160 if (app()) { |
| 156 if (app()->is_focused()) | 161 if (app()->is_focused()) |
| 157 return ProcessType::FOCUSED_APP; | 162 return ProcessType::FOCUSED_APP; |
| 158 if (app()->process_state() <= | 163 if (app()->IsImportant()) |
| 159 arc::mojom::ProcessState::IMPORTANT_FOREGROUND) { | 164 return ProcessType::IMPORTANT_APP; |
| 160 return ProcessType::VISIBLE_APP; | |
| 161 } | |
| 162 return ProcessType::BACKGROUND_APP; | 165 return ProcessType::BACKGROUND_APP; |
| 163 } | 166 } |
| 164 if (tab()) { | 167 if (tab()) { |
| 165 if (tab()->is_selected) | 168 if (tab()->is_selected) |
| 166 return ProcessType::FOCUSED_TAB; | 169 return ProcessType::FOCUSED_TAB; |
| 167 return ProcessType::BACKGROUND_TAB; | 170 return ProcessType::BACKGROUND_TAB; |
| 168 } | 171 } |
| 169 NOTREACHED() << "Unexpected process type"; | 172 NOTREACHED() << "Unexpected process type"; |
| 170 return ProcessType::UNKNOWN_TYPE; | 173 return ProcessType::UNKNOWN_TYPE; |
| 171 } | 174 } |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 524 TabManagerDelegate::GetSortedCandidates( | 527 TabManagerDelegate::GetSortedCandidates( |
| 525 const TabStatsList& tab_list, | 528 const TabStatsList& tab_list, |
| 526 const std::vector<arc::ArcProcess>& arc_processes) { | 529 const std::vector<arc::ArcProcess>& arc_processes) { |
| 527 std::vector<Candidate> candidates; | 530 std::vector<Candidate> candidates; |
| 528 candidates.reserve(tab_list.size() + arc_processes.size()); | 531 candidates.reserve(tab_list.size() + arc_processes.size()); |
| 529 | 532 |
| 530 for (const auto& tab : tab_list) { | 533 for (const auto& tab : tab_list) { |
| 531 candidates.emplace_back(&tab); | 534 candidates.emplace_back(&tab); |
| 532 } | 535 } |
| 533 | 536 |
| 534 // A special process on Android side which serves as a dummy "focused" app | |
| 535 // when the focused window is a Chrome side window (i.e., all Android | |
| 536 // processes are running in the background). We don't want to kill it anyway. | |
| 537 static constexpr char kArcInBackgroundDummyprocess[] = | |
| 538 "org.chromium.arc.home"; | |
| 539 | |
| 540 for (const auto& app : arc_processes) { | 537 for (const auto& app : arc_processes) { |
| 541 // Skip persistent android processes since they should never be killed here. | |
| 542 // Neither do we set their OOM scores so their score remains minimum. | |
| 543 if (app.process_state() <= arc::mojom::ProcessState::PERSISTENT_UI || | |
| 544 app.process_name() == kArcInBackgroundDummyprocess) { | |
| 545 continue; | |
| 546 } | |
| 547 candidates.emplace_back(&app); | 538 candidates.emplace_back(&app); |
| 548 } | 539 } |
| 549 | 540 |
| 550 // Sort candidates according to priority. | 541 // Sort candidates according to priority. |
| 551 std::sort(candidates.begin(), candidates.end()); | 542 std::sort(candidates.begin(), candidates.end()); |
| 552 | 543 |
| 553 return candidates; | 544 return candidates; |
| 554 } | 545 } |
| 555 | 546 |
| 556 bool TabManagerDelegate::IsRecentlyKilledArcProcess( | 547 bool TabManagerDelegate::IsRecentlyKilledArcProcess( |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 602 | 593 |
| 603 // Kill processes until the estimated amount of freed memory is sufficient to | 594 // Kill processes until the estimated amount of freed memory is sufficient to |
| 604 // bring the system memory back to a normal level. | 595 // bring the system memory back to a normal level. |
| 605 // The list is sorted by descending importance, so we go through the list | 596 // The list is sorted by descending importance, so we go through the list |
| 606 // backwards. | 597 // backwards. |
| 607 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { | 598 for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { |
| 608 MEMORY_LOG(ERROR) << "Target memory to free: " << target_memory_to_free_kb | 599 MEMORY_LOG(ERROR) << "Target memory to free: " << target_memory_to_free_kb |
| 609 << " KB"; | 600 << " KB"; |
| 610 if (target_memory_to_free_kb <= 0) | 601 if (target_memory_to_free_kb <= 0) |
| 611 break; | 602 break; |
| 612 // Never kill selected tab or Android foreground app, regardless whether | 603 // Never kill selected tab, foreground app, and important apps regardless of |
| 613 // they're in the active window. Since the user experience would be bad. | 604 // whether they're in the active window. Since the user experience would be |
| 605 // bad. | |
| 614 ProcessType process_type = it->process_type(); | 606 ProcessType process_type = it->process_type(); |
| 615 if (process_type == ProcessType::VISIBLE_APP || | 607 if (process_type <= ProcessType::IMPORTANT_APP) { |
| 616 process_type == ProcessType::FOCUSED_APP || | |
| 617 process_type == ProcessType::FOCUSED_TAB) { | |
| 618 MEMORY_LOG(ERROR) << "Skipped killing " << *it; | 608 MEMORY_LOG(ERROR) << "Skipped killing " << *it; |
| 619 continue; | 609 continue; |
| 620 } | 610 } |
| 621 if (it->app()) { | 611 if (it->app()) { |
| 622 if (IsRecentlyKilledArcProcess(it->app()->process_name(), now)) { | 612 if (IsRecentlyKilledArcProcess(it->app()->process_name(), now)) { |
| 623 MEMORY_LOG(ERROR) << "Avoided killing " << *it << " too often"; | 613 MEMORY_LOG(ERROR) << "Avoided killing " << *it << " too often"; |
| 624 continue; | 614 continue; |
| 625 } | 615 } |
| 626 int estimated_memory_freed_kb = | 616 int estimated_memory_freed_kb = |
| 627 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid()); | 617 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid()); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 653 } | 643 } |
| 654 if (target_memory_to_free_kb > 0) { | 644 if (target_memory_to_free_kb > 0) { |
| 655 MEMORY_LOG(ERROR) | 645 MEMORY_LOG(ERROR) |
| 656 << "Unable to kill enough candidates to meet target_memory_to_free_kb "; | 646 << "Unable to kill enough candidates to meet target_memory_to_free_kb "; |
| 657 } | 647 } |
| 658 } | 648 } |
| 659 | 649 |
| 660 void TabManagerDelegate::AdjustOomPrioritiesImpl( | 650 void TabManagerDelegate::AdjustOomPrioritiesImpl( |
| 661 const TabStatsList& tab_list, | 651 const TabStatsList& tab_list, |
| 662 const std::vector<arc::ArcProcess>& arc_processes) { | 652 const std::vector<arc::ArcProcess>& arc_processes) { |
| 653 std::vector<TabManagerDelegate::Candidate> candidates; | |
| 654 std::vector<TabManagerDelegate::Candidate> apps_non_killable; | |
| 655 | |
| 663 // Least important first. | 656 // Least important first. |
| 664 const auto candidates = GetSortedCandidates(tab_list, arc_processes); | 657 auto all_candidates = GetSortedCandidates(tab_list, arc_processes); |
| 658 for (auto& candidate : all_candidates) { | |
| 659 // TODO(cylee|yusukes): Consider using IsImportant() instead of | |
| 660 // IsKernelKillable() for simplicity. | |
| 661 // TODO(cylee): Also consider protecting FOCUSED_TAB from the kernel OOM | |
|
Yusuke Sato
2017/05/11 18:50:16
Added this to track.
cylee1
2017/05/11 19:29:14
Done.
| |
| 662 // killer so that Chrome and the kernel do the same regarding OOM handling. | |
| 663 if (!candidate.app() || candidate.app()->IsKernelKillable()) { | |
| 664 // Add tabs and killable apps to |candidates|. | |
| 665 candidates.emplace_back(std::move(candidate)); | |
| 666 } else { | |
| 667 // Add non-killable apps to |apps_non_killable|. | |
| 668 apps_non_killable.emplace_back(std::move(candidate)); | |
| 669 } | |
| 670 } | |
| 665 | 671 |
| 666 // Now we assign priorities based on the sorted list. We're assigning | 672 // Now we assign priorities based on the sorted list. We're assigning |
| 667 // priorities in the range of kLowestRendererOomScore to | 673 // priorities in the range of kLowestRendererOomScore to |
| 668 // kHighestRendererOomScore (defined in chrome_constants.h). oom_score_adj | 674 // kHighestRendererOomScore (defined in chrome_constants.h). oom_score_adj |
| 669 // takes values from -1000 to 1000. Negative values are reserved for system | 675 // takes values from -1000 to 1000. Negative values are reserved for system |
| 670 // processes, and we want to give some room below the range we're using to | 676 // processes, and we want to give some room below the range we're using to |
| 671 // allow for things that want to be above the renderers in priority, so the | 677 // allow for things that want to be above the renderers in priority, so the |
| 672 // defined range gives us some variation in priority without taking up the | 678 // defined range gives us some variation in priority without taking up the |
| 673 // whole range. In the end, however, it's a pretty arbitrary range to use. | 679 // whole range. In the end, however, it's a pretty arbitrary range to use. |
| 674 // Higher values are more likely to be killed by the OOM killer. | 680 // Higher values are more likely to be killed by the OOM killer. |
| 675 | 681 |
| 676 // Break the processes into 2 parts. This is to help lower the chance of | 682 // Break the processes into 2 parts. This is to help lower the chance of |
| 677 // altering OOM score for many processes on any small change. | 683 // altering OOM score for many processes on any small change. |
| 678 int range_middle = | 684 int range_middle = |
| 679 (chrome::kLowestRendererOomScore + chrome::kHighestRendererOomScore) / 2; | 685 (chrome::kLowestRendererOomScore + chrome::kHighestRendererOomScore) / 2; |
| 680 | 686 |
| 681 // Find some pivot point. For now processes with priority >= CHROME_INTERNAL | 687 // Find some pivot point. For now processes with priority >= CHROME_INTERNAL |
| 682 // are prone to be affected by LRU change. Taking them as "high priority" | 688 // are prone to be affected by LRU change. Taking them as "high priority" |
| 683 // processes. | 689 // processes. |
| 684 auto lower_priority_part = candidates.end(); | 690 auto lower_priority_part = candidates.end(); |
| 685 for (auto it = candidates.begin(); it != candidates.end(); ++it) { | 691 for (auto it = candidates.begin(); it != candidates.end(); ++it) { |
| 686 if (it->process_type() >= ProcessType::BACKGROUND_APP) { | 692 if (it->process_type() >= ProcessType::BACKGROUND_APP) { |
| 687 lower_priority_part = it; | 693 lower_priority_part = it; |
| 688 break; | 694 break; |
| 689 } | 695 } |
| 690 } | 696 } |
| 691 | 697 |
| 692 ProcessScoreMap new_map; | 698 ProcessScoreMap new_map; |
| 693 | 699 |
| 700 // Make the apps non-killable. | |
| 701 if (!apps_non_killable.empty()) | |
| 702 SetOomScore(apps_non_killable, kLowestOomScore, &new_map); | |
| 703 | |
| 694 // Higher priority part. | 704 // Higher priority part. |
| 695 DistributeOomScoreInRange(candidates.begin(), lower_priority_part, | 705 DistributeOomScoreInRange(candidates.begin(), lower_priority_part, |
| 696 chrome::kLowestRendererOomScore, range_middle, | 706 chrome::kLowestRendererOomScore, range_middle, |
| 697 &new_map); | 707 &new_map); |
| 698 // Lower priority part. | 708 // Lower priority part. |
| 699 DistributeOomScoreInRange(lower_priority_part, candidates.end(), range_middle, | 709 DistributeOomScoreInRange(lower_priority_part, candidates.end(), range_middle, |
| 700 chrome::kHighestRendererOomScore, &new_map); | 710 chrome::kHighestRendererOomScore, &new_map); |
| 711 | |
| 701 oom_score_map_.swap(new_map); | 712 oom_score_map_.swap(new_map); |
| 702 } | 713 } |
| 703 | 714 |
| 715 void TabManagerDelegate::SetOomScore( | |
| 716 const std::vector<TabManagerDelegate::Candidate>& candidates, | |
| 717 int score, | |
| 718 ProcessScoreMap* new_map) { | |
| 719 DistributeOomScoreInRange(candidates.begin(), candidates.end(), score, score, | |
| 720 new_map); | |
| 721 } | |
| 722 | |
| 704 void TabManagerDelegate::DistributeOomScoreInRange( | 723 void TabManagerDelegate::DistributeOomScoreInRange( |
| 705 std::vector<TabManagerDelegate::Candidate>::const_iterator begin, | 724 std::vector<TabManagerDelegate::Candidate>::const_iterator begin, |
| 706 std::vector<TabManagerDelegate::Candidate>::const_iterator end, | 725 std::vector<TabManagerDelegate::Candidate>::const_iterator end, |
| 707 int range_begin, | 726 int range_begin, |
| 708 int range_end, | 727 int range_end, |
| 709 ProcessScoreMap* new_map) { | 728 ProcessScoreMap* new_map) { |
| 710 // Processes whose OOM scores should be updated. Ignore duplicated pids but | 729 // Processes whose OOM scores should be updated. Ignore duplicated pids but |
| 711 // the last occurrence. | 730 // the last occurrence. |
| 712 std::map<base::ProcessHandle, int32_t> oom_scores_to_change; | 731 std::map<base::ProcessHandle, int32_t> oom_scores_to_change; |
| 713 | 732 |
| 714 // Though there might be duplicate process handles, it doesn't matter to | 733 // Though there might be duplicate process handles, it doesn't matter to |
| 715 // overestimate the number of processes here since the we don't need to | 734 // overestimate the number of processes here since the we don't need to |
| 716 // use up the full range. | 735 // use up the full range. |
| 717 int num = (end - begin); | 736 int num = (end - begin); |
| 718 const float priority_increment = | 737 const float priority_increment = |
| 719 static_cast<float>(range_end - range_begin) / num; | 738 static_cast<float>(range_end - range_begin) / num; |
| 720 | 739 |
| 721 float priority = range_begin; | 740 float priority = range_begin; |
| 722 for (auto cur = begin; cur != end; ++cur) { | 741 for (auto cur = begin; cur != end; ++cur) { |
| 723 int score = static_cast<int>(priority + 0.5f); | 742 const int score = round(priority); |
| 724 | 743 |
| 725 base::ProcessHandle pid = base::kNullProcessHandle; | 744 base::ProcessHandle pid = base::kNullProcessHandle; |
| 726 if (cur->app()) { | 745 if (cur->app()) { |
| 727 pid = cur->app()->pid(); | 746 pid = cur->app()->pid(); |
| 728 } else { | 747 } else { |
| 729 pid = cur->tab()->renderer_handle; | 748 pid = cur->tab()->renderer_handle; |
| 730 // 1. tab_list contains entries for already-discarded tabs. If the PID | 749 // 1. tab_list contains entries for already-discarded tabs. If the PID |
| 731 // (renderer_handle) is zero, we don't need to adjust the oom_score. | 750 // (renderer_handle) is zero, we don't need to adjust the oom_score. |
| 732 // 2. Only add unseen process handle so if there's multiple tab maps to | 751 // 2. Only add unseen process handle so if there's multiple tab maps to |
| 733 // the same process, the process is set to an OOM score based on its "most | 752 // the same process, the process is set to an OOM score based on its "most |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 746 | 765 |
| 747 // Need to update OOM score if the calculated score is different from | 766 // Need to update OOM score if the calculated score is different from |
| 748 // current cached score. | 767 // current cached score. |
| 749 if (oom_score_map_[pid] != score) { | 768 if (oom_score_map_[pid] != score) { |
| 750 VLOG(3) << "Update OOM score " << score << " for " << *cur; | 769 VLOG(3) << "Update OOM score " << score << " for " << *cur; |
| 751 oom_scores_to_change[pid] = static_cast<int32_t>(score); | 770 oom_scores_to_change[pid] = static_cast<int32_t>(score); |
| 752 } | 771 } |
| 753 priority += priority_increment; | 772 priority += priority_increment; |
| 754 } | 773 } |
| 755 | 774 |
| 756 if (oom_scores_to_change.size()) | 775 if (oom_scores_to_change.size()) { |
|
Yusuke Sato
2017/05/11 18:50:16
I believe multi-line if-body requires {}.
cylee1
2017/05/11 19:29:14
Acknowledged.
| |
| 757 GetDebugDaemonClient()->SetOomScoreAdj( | 776 GetDebugDaemonClient()->SetOomScoreAdj( |
| 758 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); | 777 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); |
| 778 } | |
| 759 } | 779 } |
| 760 | 780 |
| 761 } // namespace memory | 781 } // namespace memory |
| OLD | NEW |