OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/chromeos/memory/oom_priority_manager.h" | 5 #include "chrome/browser/chromeos/memory/oom_priority_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 str += base::ASCIIToUTF16(it->is_discarded ? " discarded" : ""); | 266 str += base::ASCIIToUTF16(it->is_discarded ? " discarded" : ""); |
267 titles.push_back(str); | 267 titles.push_back(str); |
268 } | 268 } |
269 return titles; | 269 return titles; |
270 } | 270 } |
271 | 271 |
272 // TODO(jamescook): This should consider tabs with references to other tabs, | 272 // TODO(jamescook): This should consider tabs with references to other tabs, |
273 // such as tabs created with JavaScript window.open(). We might want to | 273 // such as tabs created with JavaScript window.open(). We might want to |
274 // discard the entire set together, or use that in the priority computation. | 274 // discard the entire set together, or use that in the priority computation. |
275 bool OomPriorityManager::DiscardTab() { | 275 bool OomPriorityManager::DiscardTab() { |
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 276 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
277 TabStatsList stats = GetTabStatsOnUIThread(); | 277 TabStatsList stats = GetTabStatsOnUIThread(); |
278 if (stats.empty()) | 278 if (stats.empty()) |
279 return false; | 279 return false; |
280 // Loop until we find a non-discarded tab to kill. | 280 // Loop until we find a non-discarded tab to kill. |
281 for (TabStatsList::const_reverse_iterator stats_rit = stats.rbegin(); | 281 for (TabStatsList::const_reverse_iterator stats_rit = stats.rbegin(); |
282 stats_rit != stats.rend(); | 282 stats_rit != stats.rend(); |
283 ++stats_rit) { | 283 ++stats_rit) { |
284 int64 least_important_tab_id = stats_rit->tab_contents_id; | 284 int64 least_important_tab_id = stats_rit->tab_contents_id; |
285 if (DiscardTabById(least_important_tab_id)) | 285 if (DiscardTabById(least_important_tab_id)) |
286 return true; | 286 return true; |
287 } | 287 } |
288 return false; | 288 return false; |
289 } | 289 } |
290 | 290 |
291 void OomPriorityManager::LogMemoryAndDiscardTab() { | 291 void OomPriorityManager::LogMemoryAndDiscardTab() { |
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 292 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
293 // Deletes itself upon completion. | 293 // Deletes itself upon completion. |
294 OomMemoryDetails* details = new OomMemoryDetails(); | 294 OomMemoryDetails* details = new OomMemoryDetails(); |
295 details->StartFetch(MemoryDetails::FROM_CHROME_ONLY); | 295 details->StartFetch(MemoryDetails::FROM_CHROME_ONLY); |
296 } | 296 } |
297 | 297 |
298 /////////////////////////////////////////////////////////////////////////////// | 298 /////////////////////////////////////////////////////////////////////////////// |
299 // OomPriorityManager, private: | 299 // OomPriorityManager, private: |
300 | 300 |
301 // static | 301 // static |
302 bool OomPriorityManager::IsReloadableUI(const GURL& url) { | 302 bool OomPriorityManager::IsReloadableUI(const GURL& url) { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 | 409 |
410 int mem_available_mb = | 410 int mem_available_mb = |
411 (memory.active_file + memory.inactive_file + memory.free) / 1024; | 411 (memory.active_file + memory.inactive_file + memory.free) / 1024; |
412 UMA_HISTOGRAM_MEGABYTES("Tabs.Discard.MemAvailableMB", mem_available_mb); | 412 UMA_HISTOGRAM_MEGABYTES("Tabs.Discard.MemAvailableMB", mem_available_mb); |
413 } | 413 } |
414 // Set up to record the next interval. | 414 // Set up to record the next interval. |
415 last_discard_time_ = TimeTicks::Now(); | 415 last_discard_time_ = TimeTicks::Now(); |
416 } | 416 } |
417 | 417 |
418 void OomPriorityManager::RecordRecentTabDiscard() { | 418 void OomPriorityManager::RecordRecentTabDiscard() { |
419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 419 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
420 // If we change the interval we need to change the histogram name. | 420 // If we change the interval we need to change the histogram name. |
421 UMA_HISTOGRAM_BOOLEAN("Tabs.Discard.DiscardInLastMinute", | 421 UMA_HISTOGRAM_BOOLEAN("Tabs.Discard.DiscardInLastMinute", |
422 recent_tab_discard_); | 422 recent_tab_discard_); |
423 // Reset for the next interval. | 423 // Reset for the next interval. |
424 recent_tab_discard_ = false; | 424 recent_tab_discard_ = false; |
425 } | 425 } |
426 | 426 |
427 void OomPriorityManager::PurgeBrowserMemory() { | 427 void OomPriorityManager::PurgeBrowserMemory() { |
428 // Based on experimental evidence, attempts to free memory from renderers | 428 // Based on experimental evidence, attempts to free memory from renderers |
429 // have been too slow to use in OOM situations (V8 garbage collection) or | 429 // have been too slow to use in OOM situations (V8 garbage collection) or |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 // sudden_termination_allowed false, and that covers too many common pages | 477 // sudden_termination_allowed false, and that covers too many common pages |
478 // with ad networks and statistics scripts. Ideally we would like to check | 478 // with ad networks and statistics scripts. Ideally we would like to check |
479 // for beforeUnload handlers, which are likely to present a dialog asking | 479 // for beforeUnload handlers, which are likely to present a dialog asking |
480 // if the user wants to discard state. crbug.com/123049 | 480 // if the user wants to discard state. crbug.com/123049 |
481 | 481 |
482 // Being more recently active is more important. | 482 // Being more recently active is more important. |
483 return first.last_active > second.last_active; | 483 return first.last_active > second.last_active; |
484 } | 484 } |
485 | 485 |
486 void OomPriorityManager::AdjustFocusedTabScoreOnFileThread() { | 486 void OomPriorityManager::AdjustFocusedTabScoreOnFileThread() { |
487 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 487 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
488 base::AutoLock oom_score_autolock(oom_score_lock_); | 488 base::AutoLock oom_score_autolock(oom_score_lock_); |
489 base::ProcessHandle pid = focused_tab_process_info_.second; | 489 base::ProcessHandle pid = focused_tab_process_info_.second; |
490 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore( | 490 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore( |
491 pid, chrome::kLowestRendererOomScore); | 491 pid, chrome::kLowestRendererOomScore); |
492 oom_score_map_[focused_tab_process_info_.first] = | 492 oom_score_map_[focused_tab_process_info_.first] = |
493 chrome::kLowestRendererOomScore; | 493 chrome::kLowestRendererOomScore; |
494 } | 494 } |
495 | 495 |
496 void OomPriorityManager::OnFocusTabScoreAdjustmentTimeout() { | 496 void OomPriorityManager::OnFocusTabScoreAdjustmentTimeout() { |
497 BrowserThread::PostTask( | 497 BrowserThread::PostTask( |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 last_adjust_time_ = TimeTicks::Now(); | 589 last_adjust_time_ = TimeTicks::Now(); |
590 | 590 |
591 TabStatsList stats_list = GetTabStatsOnUIThread(); | 591 TabStatsList stats_list = GetTabStatsOnUIThread(); |
592 BrowserThread::PostTask( | 592 BrowserThread::PostTask( |
593 BrowserThread::FILE, FROM_HERE, | 593 BrowserThread::FILE, FROM_HERE, |
594 base::Bind(&OomPriorityManager::AdjustOomPrioritiesOnFileThread, | 594 base::Bind(&OomPriorityManager::AdjustOomPrioritiesOnFileThread, |
595 base::Unretained(this), stats_list)); | 595 base::Unretained(this), stats_list)); |
596 } | 596 } |
597 | 597 |
598 OomPriorityManager::TabStatsList OomPriorityManager::GetTabStatsOnUIThread() { | 598 OomPriorityManager::TabStatsList OomPriorityManager::GetTabStatsOnUIThread() { |
599 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 599 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
600 TabStatsList stats_list; | 600 TabStatsList stats_list; |
601 stats_list.reserve(32); // 99% of users have < 30 tabs open | 601 stats_list.reserve(32); // 99% of users have < 30 tabs open |
602 bool browser_active = true; | 602 bool browser_active = true; |
603 const BrowserList* ash_browser_list = | 603 const BrowserList* ash_browser_list = |
604 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); | 604 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); |
605 for (BrowserList::const_reverse_iterator browser_iterator = | 605 for (BrowserList::const_reverse_iterator browser_iterator = |
606 ash_browser_list->begin_last_active(); | 606 ash_browser_list->begin_last_active(); |
607 browser_iterator != ash_browser_list->end_last_active(); | 607 browser_iterator != ash_browser_list->end_last_active(); |
608 ++browser_iterator) { | 608 ++browser_iterator) { |
609 Browser* browser = *browser_iterator; | 609 Browser* browser = *browser_iterator; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 } | 657 } |
658 | 658 |
659 process_infos.push_back(std::make_pair( | 659 process_infos.push_back(std::make_pair( |
660 iterator->child_process_host_id, iterator->renderer_handle)); | 660 iterator->child_process_host_id, iterator->renderer_handle)); |
661 } | 661 } |
662 return process_infos; | 662 return process_infos; |
663 } | 663 } |
664 | 664 |
665 void OomPriorityManager::AdjustOomPrioritiesOnFileThread( | 665 void OomPriorityManager::AdjustOomPrioritiesOnFileThread( |
666 TabStatsList stats_list) { | 666 TabStatsList stats_list) { |
667 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 667 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
668 base::AutoLock oom_score_autolock(oom_score_lock_); | 668 base::AutoLock oom_score_autolock(oom_score_lock_); |
669 | 669 |
670 // Remove any duplicate PIDs. Order of the list is maintained, so each | 670 // Remove any duplicate PIDs. Order of the list is maintained, so each |
671 // renderer process will take on the oom_score_adj of the most important | 671 // renderer process will take on the oom_score_adj of the most important |
672 // (least likely to be killed) tab. | 672 // (least likely to be killed) tab. |
673 std::vector<ProcessInfo> process_infos = GetChildProcessInfos(stats_list); | 673 std::vector<ProcessInfo> process_infos = GetChildProcessInfos(stats_list); |
674 | 674 |
675 // Now we assign priorities based on the sorted list. We're | 675 // Now we assign priorities based on the sorted list. We're |
676 // assigning priorities in the range of kLowestRendererOomScore to | 676 // assigning priorities in the range of kLowestRendererOomScore to |
677 // kHighestRendererOomScore (defined in chrome_constants.h). | 677 // kHighestRendererOomScore (defined in chrome_constants.h). |
(...skipping 29 matching lines...) Expand all Loading... |
707 // For the moment we only do something when we reach a critical state. | 707 // For the moment we only do something when we reach a critical state. |
708 if (memory_pressure_level == | 708 if (memory_pressure_level == |
709 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) { | 709 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) { |
710 LogMemoryAndDiscardTab(); | 710 LogMemoryAndDiscardTab(); |
711 } | 711 } |
712 // TODO(skuhne): If more memory pressure levels are introduced, we might | 712 // TODO(skuhne): If more memory pressure levels are introduced, we might |
713 // consider to call PurgeBrowserMemory() before CRITICAL is reached. | 713 // consider to call PurgeBrowserMemory() before CRITICAL is reached. |
714 } | 714 } |
715 | 715 |
716 } // namespace chromeos | 716 } // namespace chromeos |
OLD | NEW |