summaryrefslogtreecommitdiffstats
path: root/chrome/browser/oom_priority_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/oom_priority_manager.cc')
-rw-r--r--chrome/browser/oom_priority_manager.cc176
1 files changed, 0 insertions, 176 deletions
diff --git a/chrome/browser/oom_priority_manager.cc b/chrome/browser/oom_priority_manager.cc
deleted file mode 100644
index f841570..0000000
--- a/chrome/browser/oom_priority_manager.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/oom_priority_manager.h"
-
-#include <list>
-
-#include "base/process.h"
-#include "base/process_util.h"
-#include "base/thread.h"
-#include "build/build_config.h"
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/renderer_host/render_process_host.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
-#include "chrome/browser/tabs/tab_strip_model.h"
-#include "chrome/browser/zygote_host_linux.h"
-
-#if !defined(OS_CHROMEOS)
-#error This file only meant to be compiled on ChromeOS
-#endif
-
-using base::TimeDelta;
-using base::TimeTicks;
-using base::ProcessHandle;
-using base::ProcessMetrics;
-
-namespace browser {
-
-// The default interval in seconds after which to adjust the oom_adj
-// value.
-#define ADJUSTMENT_INTERVAL_SECONDS 10
-
-// The default interval in minutes for considering activation times
-// "equal".
-#define BUCKET_INTERVAL_MINUTES 10
-
-OomPriorityManager::OomPriorityManager() {
- StartTimer();
-}
-
-OomPriorityManager::~OomPriorityManager() {
- StopTimer();
-}
-
-void OomPriorityManager::StartTimer() {
- if (!timer_.IsRunning()) {
- timer_.Start(TimeDelta::FromSeconds(ADJUSTMENT_INTERVAL_SECONDS),
- this,
- &OomPriorityManager::AdjustOomPriorities);
- }
-}
-
-void OomPriorityManager::StopTimer() {
- timer_.Stop();
-}
-
-// Returns true if |first| is considered less desirable to be killed
-// than |second|.
-bool OomPriorityManager::CompareRendererStats(RendererStats first,
- RendererStats second) {
- // The size of the slop in comparing activation times. [This is
- // allocated here to avoid static initialization at startup time.]
- static const int64 kTimeBucketInterval =
- TimeDelta::FromMinutes(BUCKET_INTERVAL_MINUTES).ToInternalValue();
-
- // Being pinned is most important.
- if (first.is_pinned != second.is_pinned)
- return first.is_pinned == true;
-
- // We want to be a little "fuzzy" when we compare these, because
- // it's not really possible for the times to be identical, but if
- // the user selected two tabs at about the same time, we still want
- // to take the one that uses more memory.
- if (abs((first.last_selected - second.last_selected).ToInternalValue()) <
- kTimeBucketInterval)
- return first.last_selected < second.last_selected;
-
- return first.memory_used < second.memory_used;
-}
-
-// Here we collect most of the information we need to sort the
-// existing renderers in priority order, and hand out oom_adj scores
-// based on that sort order.
-//
-// Things we need to collect on the browser thread (because
-// TabStripModel isn't thread safe):
-// 1) whether or not a tab is pinned
-// 2) last time a tab was selected
-//
-// We also need to collect:
-// 3) size in memory of a tab
-// But we do that in DoAdjustOomPriorities on the FILE thread so that
-// we avoid jank, because it accesses /proc.
-void OomPriorityManager::AdjustOomPriorities() {
- if (BrowserList::size() == 0)
- return;
-
- StatsList renderer_stats;
- for (BrowserList::const_iterator browser_iterator = BrowserList::begin();
- browser_iterator != BrowserList::end(); ++browser_iterator) {
- Browser* browser = *browser_iterator;
- const TabStripModel* model = browser->tabstrip_model();
- for (int i = 0; i < model->count(); i++) {
- TabContents* contents = model->GetTabContentsAt(i)->tab_contents();
- RendererStats stats;
- stats.last_selected = contents->last_selected_time();
- stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle();
- stats.is_pinned = model->IsTabPinned(i);
- renderer_stats.push_back(stats);
- }
- }
-
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &OomPriorityManager::DoAdjustOomPriorities,
- renderer_stats));
-}
-
-void OomPriorityManager::DoAdjustOomPriorities(StatsList renderer_stats) {
- for (StatsList::iterator stats_iter = renderer_stats.begin();
- stats_iter != renderer_stats.end(); ++stats_iter) {
- scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics(
- stats_iter->renderer_handle));
-
- base::WorkingSetKBytes working_set_kbytes;
- if (metrics->GetWorkingSetKBytes(&working_set_kbytes)) {
- // We use the proportional set size (PSS) to calculate memory
- // usage "badness" on Linux.
- stats_iter->memory_used = working_set_kbytes.shared * 1024;
- } else {
- // and if for some reason we can't get PSS, we revert to using
- // resident set size (RSS). This will be zero if the process
- // has already gone away, but we can live with that, since the
- // process is gone anyhow.
- stats_iter->memory_used = metrics->GetWorkingSetSize();
- }
- }
-
- // Now we sort the data we collected so that least desirable to be
- // killed is first, most desirable is last.
- renderer_stats.sort(OomPriorityManager::CompareRendererStats);
-
- // Now we assign priorities based on the sorted list. We're
- // assigning priorities in the range of 5 to 10. oom_adj takes
- // values from -17 to 15. Negative values are reserved for system
- // processes, and we want to give some room on either side of the
- // range we're using to allow for things that want to be above or
- // below the renderers in priority, so 5 to 10 gives us some
- // variation in priority without taking up the whole range. In the
- // end, however, it's a pretty arbitrary range to use. Higher
- // values are more likely to be killed by the OOM killer. We also
- // remove any duplicate PIDs, leaving the most important of the
- // duplicates.
- const int kMinPriority = 5;
- const int kMaxPriority = 10;
- const int kPriorityRange = kMaxPriority - kMinPriority;
- float priority_increment =
- static_cast<float>(kPriorityRange) / renderer_stats.size();
- float priority = kMinPriority;
- std::set<base::ProcessHandle> already_seen;
- for (StatsList::iterator iterator = renderer_stats.begin();
- iterator != renderer_stats.end(); ++iterator) {
- if (already_seen.find(iterator->renderer_handle) == already_seen.end()) {
- already_seen.insert(iterator->renderer_handle);
- Singleton<ZygoteHost>::get()->AdjustRendererOOMScore(
- iterator->renderer_handle,
- static_cast<int>(priority + 0.5f));
- priority += priority_increment;
- }
- }
-}
-
-} // namespace browser