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

Side by Side Diff: chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc

Issue 2898033002: [TabManager] Move TabManager into chrome/browser/resource_coordinator. (Closed)
Patch Set: rebase Created 3 years, 6 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/resource_coordinator/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>
11 #include <map> 11 #include <map>
12 #include <vector> 12 #include <vector>
13 13
14 #include "ash/shell.h" 14 #include "ash/shell.h"
15 #include "base/bind.h" 15 #include "base/bind.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/files/file_path.h" 17 #include "base/files/file_path.h"
18 #include "base/files/file_util.h" 18 #include "base/files/file_util.h"
19 #include "base/memory/memory_pressure_monitor_chromeos.h" 19 #include "base/memory/memory_pressure_monitor_chromeos.h"
20 #include "base/metrics/histogram_macros.h" 20 #include "base/metrics/histogram_macros.h"
21 #include "base/process/process_handle.h" // kNullProcessHandle. 21 #include "base/process/process_handle.h" // kNullProcessHandle.
22 #include "base/process/process_metrics.h" 22 #include "base/process/process_metrics.h"
23 #include "base/strings/string16.h" 23 #include "base/strings/string16.h"
24 #include "base/strings/string_number_conversions.h" 24 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/string_util.h" 25 #include "base/strings/string_util.h"
26 #include "base/strings/utf_string_conversions.h" 26 #include "base/strings/utf_string_conversions.h"
27 #include "base/time/time.h" 27 #include "base/time/time.h"
28 #include "chrome/browser/chromeos/arc/process/arc_process.h" 28 #include "chrome/browser/chromeos/arc/process/arc_process.h"
29 #include "chrome/browser/chromeos/arc/process/arc_process_service.h" 29 #include "chrome/browser/chromeos/arc/process/arc_process_service.h"
30 #include "chrome/browser/memory/memory_kills_monitor.h" 30 #include "chrome/browser/memory/memory_kills_monitor.h"
31 #include "chrome/browser/memory/tab_stats.h" 31 #include "chrome/browser/resource_coordinator/tab_stats.h"
32 #include "chrome/browser/ui/browser.h" 32 #include "chrome/browser/ui/browser.h"
33 #include "chrome/browser/ui/browser_list.h" 33 #include "chrome/browser/ui/browser_list.h"
34 #include "chrome/browser/ui/tabs/tab_strip_model.h" 34 #include "chrome/browser/ui/tabs/tab_strip_model.h"
35 #include "chrome/common/chrome_constants.h" 35 #include "chrome/common/chrome_constants.h"
36 #include "chrome/common/chrome_features.h" 36 #include "chrome/common/chrome_features.h"
37 #include "chromeos/dbus/dbus_thread_manager.h" 37 #include "chromeos/dbus/dbus_thread_manager.h"
38 #include "components/arc/arc_bridge_service.h" 38 #include "components/arc/arc_bridge_service.h"
39 #include "components/arc/arc_service_manager.h" 39 #include "components/arc/arc_service_manager.h"
40 #include "components/arc/arc_util.h" 40 #include "components/arc/arc_util.h"
41 #include "components/device_event_log/device_event_log.h" 41 #include "components/device_event_log/device_event_log.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/wm/public/activation_client.h" 48 #include "ui/wm/public/activation_client.h"
49 49
50 using base::ProcessHandle; 50 using base::ProcessHandle;
51 using base::TimeDelta; 51 using base::TimeDelta;
52 using base::TimeTicks; 52 using base::TimeTicks;
53 using content::BrowserThread; 53 using content::BrowserThread;
54 54
55 namespace memory { 55 namespace resource_coordinator {
56 namespace { 56 namespace {
57 57
58 // When switching to a new tab the tab's renderer's OOM score needs to be 58 // When switching to a new tab the tab's renderer's OOM score needs to be
59 // updated to reflect its front-most status and protect it from discard. 59 // updated to reflect its front-most status and protect it from discard.
60 // However, doing this immediately might slow down tab switch time, so wait 60 // However, doing this immediately might slow down tab switch time, so wait
61 // a little while before doing the adjustment. 61 // a little while before doing the adjustment.
62 const int kFocusedProcessScoreAdjustIntervalMs = 500; 62 const int kFocusedProcessScoreAdjustIntervalMs = 500;
63 63
64 wm::ActivationClient* GetActivationClient() { 64 wm::ActivationClient* GetActivationClient() {
65 if (!ash::Shell::HasInstance()) 65 if (!ash::Shell::HasInstance())
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 return os << "BACKGROUND_APP"; 98 return os << "BACKGROUND_APP";
99 case ProcessType::UNKNOWN_TYPE: 99 case ProcessType::UNKNOWN_TYPE:
100 return os << "UNKNOWN_TYPE"; 100 return os << "UNKNOWN_TYPE";
101 default: 101 default:
102 return os << "NOT_IMPLEMENTED_ERROR"; 102 return os << "NOT_IMPLEMENTED_ERROR";
103 } 103 }
104 return os; 104 return os;
105 } 105 }
106 106
107 // TabManagerDelegate::Candidate implementation. 107 // TabManagerDelegate::Candidate implementation.
108 std::ostream& operator<<( 108 std::ostream& operator<<(std::ostream& out,
109 std::ostream& out, const TabManagerDelegate::Candidate& candidate) { 109 const TabManagerDelegate::Candidate& candidate) {
110 if (candidate.app()) { 110 if (candidate.app()) {
111 out << "app " << *candidate.app(); 111 out << "app " << *candidate.app();
112 } else if (candidate.tab()) { 112 } else if (candidate.tab()) {
113 const TabStats* const& tab = candidate.tab(); 113 const TabStats* const& tab = candidate.tab();
114 out << "tab " << tab->title << ", renderer_handle: " << tab->renderer_handle 114 out << "tab " << tab->title << ", renderer_handle: " << tab->renderer_handle
115 << ", oom_score: " << tab->oom_score 115 << ", oom_score: " << tab->oom_score
116 << ", is_discarded: " << tab->is_discarded 116 << ", is_discarded: " << tab->is_discarded
117 << ", discard_count: " << tab->discard_count 117 << ", discard_count: " << tab->discard_count
118 << ", last_active: " << tab->last_active; 118 << ", last_active: " << tab->last_active;
119 } 119 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 207
208 // If a chrome tab. 208 // If a chrome tab.
209 base::ProcessHandle pid_; 209 base::ProcessHandle pid_;
210 // If an Android app. 210 // If an Android app.
211 int nspid_; 211 int nspid_;
212 }; 212 };
213 213
214 // TabManagerDelegate::MemoryStat implementation. 214 // TabManagerDelegate::MemoryStat implementation.
215 215
216 // static 216 // static
217 int TabManagerDelegate::MemoryStat::ReadIntFromFile( 217 int TabManagerDelegate::MemoryStat::ReadIntFromFile(const char* file_name,
218 const char* file_name, const int default_val) { 218 const int default_val) {
219 std::string file_string; 219 std::string file_string;
220 if (!base::ReadFileToString(base::FilePath(file_name), &file_string)) { 220 if (!base::ReadFileToString(base::FilePath(file_name), &file_string)) {
221 LOG(WARNING) << "Unable to read file" << file_name; 221 LOG(WARNING) << "Unable to read file" << file_name;
222 return default_val; 222 return default_val;
223 } 223 }
224 int val = default_val; 224 int val = default_val;
225 if (!base::StringToInt( 225 if (!base::StringToInt(
226 base::TrimWhitespaceASCII(file_string, base::TRIM_TRAILING), 226 base::TrimWhitespaceASCII(file_string, base::TRIM_TRAILING), &val)) {
227 &val)) {
228 LOG(WARNING) << "Unable to parse string" << file_string; 227 LOG(WARNING) << "Unable to parse string" << file_string;
229 return default_val; 228 return default_val;
230 } 229 }
231 return val; 230 return val;
232 } 231 }
233 232
234 // static 233 // static
235 int TabManagerDelegate::MemoryStat::LowMemoryMarginKB() { 234 int TabManagerDelegate::MemoryStat::LowMemoryMarginKB() {
236 static const int kDefaultLowMemoryMarginMb = 50; 235 static const int kDefaultLowMemoryMarginMb = 50;
237 static const char kLowMemoryMarginConfig[] = 236 static const char kLowMemoryMarginConfig[] =
238 "/sys/kernel/mm/chromeos-low_mem/margin"; 237 "/sys/kernel/mm/chromeos-low_mem/margin";
239 return ReadIntFromFile( 238 return ReadIntFromFile(kLowMemoryMarginConfig, kDefaultLowMemoryMarginMb) *
240 kLowMemoryMarginConfig, kDefaultLowMemoryMarginMb) * 1024; 239 1024;
241 } 240 }
242 241
243 // The logic of available memory calculation is copied from 242 // The logic of available memory calculation is copied from
244 // _is_low_mem_situation() in kernel file include/linux/low-mem-notify.h. 243 // _is_low_mem_situation() in kernel file include/linux/low-mem-notify.h.
245 // Maybe we should let kernel report the number directly. 244 // Maybe we should let kernel report the number directly.
246 int TabManagerDelegate::MemoryStat::TargetMemoryToFreeKB() { 245 int TabManagerDelegate::MemoryStat::TargetMemoryToFreeKB() {
247 static const int kRamVsSwapWeight = 4; 246 static const int kRamVsSwapWeight = 4;
248 static const char kMinFilelistConfig[] = "/proc/sys/vm/min_filelist_kbytes"; 247 static const char kMinFilelistConfig[] = "/proc/sys/vm/min_filelist_kbytes";
249 static const char kMinFreeKbytes[] = "/proc/sys/vm/min_free_kbytes"; 248 static const char kMinFreeKbytes[] = "/proc/sys/vm/min_free_kbytes";
250 249
251 base::SystemMemoryInfoKB system_mem; 250 base::SystemMemoryInfoKB system_mem;
252 base::GetSystemMemoryInfo(&system_mem); 251 base::GetSystemMemoryInfo(&system_mem);
253 const int file_mem_kb = system_mem.active_file + system_mem.inactive_file; 252 const int file_mem_kb = system_mem.active_file + system_mem.inactive_file;
254 const int min_filelist_kb = ReadIntFromFile(kMinFilelistConfig, 0); 253 const int min_filelist_kb = ReadIntFromFile(kMinFilelistConfig, 0);
255 const int min_free_kb = ReadIntFromFile(kMinFreeKbytes, 0); 254 const int min_free_kb = ReadIntFromFile(kMinFreeKbytes, 0);
256 // Calculate current available memory in system. 255 // Calculate current available memory in system.
257 // File-backed memory should be easy to reclaim, unless they're dirty. 256 // File-backed memory should be easy to reclaim, unless they're dirty.
258 // TODO(cylee): On ChromeOS, kernel reports low memory condition when 257 // TODO(cylee): On ChromeOS, kernel reports low memory condition when
259 // available memory is low. The following formula duplicates the logic in 258 // available memory is low. The following formula duplicates the logic in
260 // kernel to calculate how much memory should be released. In the future, 259 // kernel to calculate how much memory should be released. In the future,
261 // kernel should try to report the amount of memory to release directly to 260 // kernel should try to report the amount of memory to release directly to
262 // eliminate the duplication here. 261 // eliminate the duplication here.
263 const int available_mem_kb = system_mem.free + 262 const int available_mem_kb =
264 file_mem_kb - system_mem.dirty - min_filelist_kb + 263 system_mem.free + file_mem_kb - system_mem.dirty - min_filelist_kb +
265 system_mem.swap_free / kRamVsSwapWeight - 264 system_mem.swap_free / kRamVsSwapWeight - min_free_kb;
266 min_free_kb;
267 265
268 return LowMemoryMarginKB() - available_mem_kb; 266 return LowMemoryMarginKB() - available_mem_kb;
269 } 267 }
270 268
271 int TabManagerDelegate::MemoryStat::EstimatedMemoryFreedKB( 269 int TabManagerDelegate::MemoryStat::EstimatedMemoryFreedKB(
272 base::ProcessHandle pid) { 270 base::ProcessHandle pid) {
273 std::unique_ptr<base::ProcessMetrics> process_metrics( 271 std::unique_ptr<base::ProcessMetrics> process_metrics(
274 base::ProcessMetrics::CreateProcessMetrics(pid)); 272 base::ProcessMetrics::CreateProcessMetrics(pid));
275 base::WorkingSetKBytes mem_usage; 273 base::WorkingSetKBytes mem_usage;
276 process_metrics->GetWorkingSetKBytes(&mem_usage); 274 process_metrics->GetWorkingSetKBytes(&mem_usage);
277 return mem_usage.priv; 275 return mem_usage.priv;
278 } 276 }
279 277
280 TabManagerDelegate::TabManagerDelegate( 278 TabManagerDelegate::TabManagerDelegate(
281 const base::WeakPtr<TabManager>& tab_manager) 279 const base::WeakPtr<TabManager>& tab_manager)
282 : TabManagerDelegate(tab_manager, new MemoryStat()) { 280 : TabManagerDelegate(tab_manager, new MemoryStat()) {}
283 }
284 281
285 TabManagerDelegate::TabManagerDelegate( 282 TabManagerDelegate::TabManagerDelegate(
286 const base::WeakPtr<TabManager>& tab_manager, 283 const base::WeakPtr<TabManager>& tab_manager,
287 TabManagerDelegate::MemoryStat* mem_stat) 284 TabManagerDelegate::MemoryStat* mem_stat)
288 : tab_manager_(tab_manager), 285 : tab_manager_(tab_manager),
289 focused_process_(new FocusedProcess()), 286 focused_process_(new FocusedProcess()),
290 mem_stat_(mem_stat), 287 mem_stat_(mem_stat),
291 weak_ptr_factory_(this) { 288 weak_ptr_factory_(this) {
292 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 289 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
293 content::NotificationService::AllBrowserContextsAndSources()); 290 content::NotificationService::AllBrowserContextsAndSources());
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 // window, so schedule an early adjustment for all processes to reflect 330 // window, so schedule an early adjustment for all processes to reflect
334 // the change. 331 // the change.
335 // Put a dummy FocusedProcess with nspid = kInvalidArcAppNspid for now to 332 // Put a dummy FocusedProcess with nspid = kInvalidArcAppNspid for now to
336 // indicate the focused process is an arc app. 333 // indicate the focused process is an arc app.
337 // TODO(cylee): Fix it when we have nspid info in ARC windows. 334 // TODO(cylee): Fix it when we have nspid info in ARC windows.
338 focused_process_->SetArcAppNspid(FocusedProcess::kInvalidArcAppNspid); 335 focused_process_->SetArcAppNspid(FocusedProcess::kInvalidArcAppNspid);
339 // If the timer is already running (possibly for a tab), it'll be reset 336 // If the timer is already running (possibly for a tab), it'll be reset
340 // here. 337 // here.
341 focus_process_score_adjust_timer_.Start( 338 focus_process_score_adjust_timer_.Start(
342 FROM_HERE, 339 FROM_HERE,
343 TimeDelta::FromMilliseconds(kFocusedProcessScoreAdjustIntervalMs), 340 TimeDelta::FromMilliseconds(kFocusedProcessScoreAdjustIntervalMs), this,
344 this, &TabManagerDelegate::ScheduleEarlyOomPrioritiesAdjustment); 341 &TabManagerDelegate::ScheduleEarlyOomPrioritiesAdjustment);
345 } 342 }
346 if (arc::IsArcAppWindow(lost_active)) { 343 if (arc::IsArcAppWindow(lost_active)) {
347 // Do not bother adjusting OOM score if the ARC window is deactivated 344 // Do not bother adjusting OOM score if the ARC window is deactivated
348 // shortly. 345 // shortly.
349 if (focused_process_->ResetIfIsArcApp() && 346 if (focused_process_->ResetIfIsArcApp() &&
350 focus_process_score_adjust_timer_.IsRunning()) 347 focus_process_score_adjust_timer_.IsRunning())
351 focus_process_score_adjust_timer_.Stop(); 348 focus_process_score_adjust_timer_.Stop();
352 } 349 }
353 } 350 }
354 351
355 void TabManagerDelegate::ScheduleEarlyOomPrioritiesAdjustment() { 352 void TabManagerDelegate::ScheduleEarlyOomPrioritiesAdjustment() {
356 DCHECK_CURRENTLY_ON(BrowserThread::UI); 353 DCHECK_CURRENTLY_ON(BrowserThread::UI);
357 if (tab_manager_) { 354 if (tab_manager_) {
358 AdjustOomPriorities(tab_manager_->GetUnsortedTabStats()); 355 AdjustOomPriorities(tab_manager_->GetUnsortedTabStats());
359 } 356 }
360 } 357 }
361 358
362 // If able to get the list of ARC procsses, prioritize tabs and apps as a whole. 359 // If able to get the list of ARC procsses, prioritize tabs and apps as a whole.
363 // Otherwise try to kill tabs only. 360 // Otherwise try to kill tabs only.
364 void TabManagerDelegate::LowMemoryKill( 361 void TabManagerDelegate::LowMemoryKill(const TabStatsList& tab_list) {
365 const TabStatsList& tab_list) {
366 arc::ArcProcessService* arc_process_service = arc::ArcProcessService::Get(); 362 arc::ArcProcessService* arc_process_service = arc::ArcProcessService::Get();
367 if (arc_process_service && 363 if (arc_process_service &&
368 arc_process_service->RequestAppProcessList( 364 arc_process_service->RequestAppProcessList(
369 base::Bind(&TabManagerDelegate::LowMemoryKillImpl, 365 base::Bind(&TabManagerDelegate::LowMemoryKillImpl,
370 weak_ptr_factory_.GetWeakPtr(), tab_list))) { 366 weak_ptr_factory_.GetWeakPtr(), tab_list))) {
371 // LowMemoryKillImpl will be called asynchronously so nothing left to do. 367 // LowMemoryKillImpl will be called asynchronously so nothing left to do.
372 return; 368 return;
373 } 369 }
374 // If the list of ARC processes is not available, call LowMemoryKillImpl 370 // If the list of ARC processes is not available, call LowMemoryKillImpl
375 // synchronously with an empty list of apps. 371 // synchronously with an empty list of apps.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 it->second != chrome::kLowestRendererOomScore); 418 it->second != chrome::kLowestRendererOomScore);
423 419
424 if (not_lowest_score) { 420 if (not_lowest_score) {
425 // By starting a timer we guarantee that the tab is focused for 421 // By starting a timer we guarantee that the tab is focused for
426 // certain amount of time. Secondly, it also does not add overhead 422 // certain amount of time. Secondly, it also does not add overhead
427 // to the tab switching time. 423 // to the tab switching time.
428 // If there's an existing running timer (could be for ARC app), it 424 // If there's an existing running timer (could be for ARC app), it
429 // would be replaced by a new task. 425 // would be replaced by a new task.
430 focus_process_score_adjust_timer_.Start( 426 focus_process_score_adjust_timer_.Start(
431 FROM_HERE, 427 FROM_HERE,
432 TimeDelta::FromMilliseconds(kFocusedProcessScoreAdjustIntervalMs), 428 TimeDelta::FromMilliseconds(kFocusedProcessScoreAdjustIntervalMs), this,
433 this, &TabManagerDelegate::OnFocusTabScoreAdjustmentTimeout); 429 &TabManagerDelegate::OnFocusTabScoreAdjustmentTimeout);
434 } 430 }
435 } 431 }
436 432
437 void TabManagerDelegate::Observe(int type, 433 void TabManagerDelegate::Observe(int type,
438 const content::NotificationSource& source, 434 const content::NotificationSource& source,
439 const content::NotificationDetails& details) { 435 const content::NotificationDetails& details) {
440 switch (type) { 436 switch (type) {
441 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: 437 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED:
442 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { 438 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
443 content::RenderProcessHost* host = 439 content::RenderProcessHost* host =
(...skipping 12 matching lines...) Expand all
456 base::chromeos::MemoryPressureMonitor::Get(); 452 base::chromeos::MemoryPressureMonitor::Get();
457 if (monitor) 453 if (monitor)
458 monitor->ScheduleEarlyCheck(); 454 monitor->ScheduleEarlyCheck();
459 break; 455 break;
460 } 456 }
461 case content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED: { 457 case content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED: {
462 bool visible = *content::Details<bool>(details).ptr(); 458 bool visible = *content::Details<bool>(details).ptr();
463 if (visible) { 459 if (visible) {
464 content::RenderProcessHost* render_host = 460 content::RenderProcessHost* render_host =
465 content::Source<content::RenderWidgetHost>(source) 461 content::Source<content::RenderWidgetHost>(source)
466 .ptr() 462 .ptr()
467 ->GetProcess(); 463 ->GetProcess();
468 AdjustFocusedTabScore(render_host->GetHandle()); 464 AdjustFocusedTabScore(render_host->GetHandle());
469 } 465 }
470 // Do not handle the "else" case when it changes to invisible because 466 // Do not handle the "else" case when it changes to invisible because
471 // 1. The behavior is a bit awkward in that when switching from tab A to 467 // 1. The behavior is a bit awkward in that when switching from tab A to
472 // tab B, the event "invisible of B" comes after "visible of A". It can 468 // tab B, the event "invisible of B" comes after "visible of A". It can
473 // cause problems when the 2 tabs have the same content (e.g., New Tab 469 // cause problems when the 2 tabs have the same content (e.g., New Tab
474 // Page). To be more clear, if we try to cancel the timer when losing 470 // Page). To be more clear, if we try to cancel the timer when losing
475 // focus it may cancel the timer for the same renderer process. 471 // focus it may cancel the timer for the same renderer process.
476 // 2. When another window is launched on top of an existing browser 472 // 2. When another window is launched on top of an existing browser
477 // window, the selected tab in the existing browser didn't receive this 473 // window, the selected tab in the existing browser didn't receive this
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 arc_service_manager->arc_bridge_service()->process(), KillProcess); 546 arc_service_manager->arc_bridge_service()->process(), KillProcess);
551 if (!arc_process_instance) 547 if (!arc_process_instance)
552 return false; 548 return false;
553 549
554 arc_process_instance->KillProcess(nspid, "LowMemoryKill"); 550 arc_process_instance->KillProcess(nspid, "LowMemoryKill");
555 return true; 551 return true;
556 } 552 }
557 553
558 bool TabManagerDelegate::KillTab(int64_t tab_id) { 554 bool TabManagerDelegate::KillTab(int64_t tab_id) {
559 // Check |tab_manager_| is alive before taking tabs into consideration. 555 // Check |tab_manager_| is alive before taking tabs into consideration.
560 return tab_manager_ && 556 return tab_manager_ && tab_manager_->CanDiscardTab(tab_id) &&
561 tab_manager_->CanDiscardTab(tab_id) && 557 tab_manager_->DiscardTabById(tab_id);
562 tab_manager_->DiscardTabById(tab_id);
563 } 558 }
564 559
565
566 chromeos::DebugDaemonClient* TabManagerDelegate::GetDebugDaemonClient() { 560 chromeos::DebugDaemonClient* TabManagerDelegate::GetDebugDaemonClient() {
567 return chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); 561 return chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
568 } 562 }
569 563
570 void TabManagerDelegate::LowMemoryKillImpl( 564 void TabManagerDelegate::LowMemoryKillImpl(
571 const TabStatsList& tab_list, 565 const TabStatsList& tab_list,
572 const std::vector<arc::ArcProcess>& arc_processes) { 566 const std::vector<arc::ArcProcess>& arc_processes) {
573 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 567 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
574 VLOG(2) << "LowMemoryKillImpl"; 568 VLOG(2) << "LowMemoryKillImpl";
575 569
(...skipping 29 matching lines...) Expand all
605 if (IsRecentlyKilledArcProcess(it->app()->process_name(), now)) { 599 if (IsRecentlyKilledArcProcess(it->app()->process_name(), now)) {
606 MEMORY_LOG(ERROR) << "Avoided killing " << it->app()->process_name() 600 MEMORY_LOG(ERROR) << "Avoided killing " << it->app()->process_name()
607 << " too often"; 601 << " too often";
608 continue; 602 continue;
609 } 603 }
610 int estimated_memory_freed_kb = 604 int estimated_memory_freed_kb =
611 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid()); 605 mem_stat_->EstimatedMemoryFreedKB(it->app()->pid());
612 if (KillArcProcess(it->app()->nspid())) { 606 if (KillArcProcess(it->app()->nspid())) {
613 recently_killed_arc_processes_[it->app()->process_name()] = now; 607 recently_killed_arc_processes_[it->app()->process_name()] = now;
614 target_memory_to_free_kb -= estimated_memory_freed_kb; 608 target_memory_to_free_kb -= estimated_memory_freed_kb;
615 MemoryKillsMonitor::LogLowMemoryKill("APP", estimated_memory_freed_kb); 609 memory::MemoryKillsMonitor::LogLowMemoryKill("APP",
610 estimated_memory_freed_kb);
616 MEMORY_LOG(ERROR) << "Killed app " << it->app()->process_name() << " (" 611 MEMORY_LOG(ERROR) << "Killed app " << it->app()->process_name() << " ("
617 << it->app()->pid() << ")" 612 << it->app()->pid() << ")"
618 << ", estimated " << estimated_memory_freed_kb 613 << ", estimated " << estimated_memory_freed_kb
619 << " KB freed"; 614 << " KB freed";
620 } else { 615 } else {
621 MEMORY_LOG(ERROR) << "Failed to kill " << it->app()->process_name(); 616 MEMORY_LOG(ERROR) << "Failed to kill " << it->app()->process_name();
622 } 617 }
623 } else { 618 } else {
624 int64_t tab_id = it->tab()->tab_contents_id; 619 int64_t tab_id = it->tab()->tab_contents_id;
625 // The estimation is problematic since multiple tabs may share the same 620 // The estimation is problematic since multiple tabs may share the same
626 // process, while the calculation counts memory used by the whole process. 621 // process, while the calculation counts memory used by the whole process.
627 // So |estimated_memory_freed_kb| is an over-estimation. 622 // So |estimated_memory_freed_kb| is an over-estimation.
628 int estimated_memory_freed_kb = 623 int estimated_memory_freed_kb =
629 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle); 624 mem_stat_->EstimatedMemoryFreedKB(it->tab()->renderer_handle);
630 if (KillTab(tab_id)) { 625 if (KillTab(tab_id)) {
631 target_memory_to_free_kb -= estimated_memory_freed_kb; 626 target_memory_to_free_kb -= estimated_memory_freed_kb;
632 MemoryKillsMonitor::LogLowMemoryKill("TAB", estimated_memory_freed_kb); 627 memory::MemoryKillsMonitor::LogLowMemoryKill("TAB",
628 estimated_memory_freed_kb);
633 MEMORY_LOG(ERROR) << "Killed tab " << it->tab()->title << " (" 629 MEMORY_LOG(ERROR) << "Killed tab " << it->tab()->title << " ("
634 << it->tab()->renderer_handle << "), estimated " 630 << it->tab()->renderer_handle << "), estimated "
635 << estimated_memory_freed_kb << " KB freed"; 631 << estimated_memory_freed_kb << " KB freed";
636 } 632 }
637 } 633 }
638 } 634 }
639 if (target_memory_to_free_kb > 0) { 635 if (target_memory_to_free_kb > 0) {
640 MEMORY_LOG(ERROR) 636 MEMORY_LOG(ERROR)
641 << "Unable to kill enough candidates to meet target_memory_to_free_kb "; 637 << "Unable to kill enough candidates to meet target_memory_to_free_kb ";
642 } 638 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 // Need to update OOM score if the calculated score is different from 757 // Need to update OOM score if the calculated score is different from
762 // current cached score. 758 // current cached score.
763 if (oom_score_map_[pid] != score) { 759 if (oom_score_map_[pid] != score) {
764 VLOG(3) << "Update OOM score " << score << " for " << *cur; 760 VLOG(3) << "Update OOM score " << score << " for " << *cur;
765 oom_scores_to_change[pid] = static_cast<int32_t>(score); 761 oom_scores_to_change[pid] = static_cast<int32_t>(score);
766 } 762 }
767 priority += priority_increment; 763 priority += priority_increment;
768 } 764 }
769 765
770 if (oom_scores_to_change.size()) { 766 if (oom_scores_to_change.size()) {
771 GetDebugDaemonClient()->SetOomScoreAdj( 767 GetDebugDaemonClient()->SetOomScoreAdj(oom_scores_to_change,
772 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); 768 base::Bind(&OnSetOomScoreAdj));
773 } 769 }
774 } 770 }
775 771
776 } // namespace memory 772 } // namespace resource_coordinator
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698