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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 using content::BrowserThread; | 50 using content::BrowserThread; |
51 using content::WebContents; | 51 using content::WebContents; |
52 | 52 |
53 namespace chromeos { | 53 namespace chromeos { |
54 | 54 |
55 namespace { | 55 namespace { |
56 | 56 |
57 // Name of the experiment to run. | 57 // Name of the experiment to run. |
58 const char kExperiment[] = "LowMemoryMargin"; | 58 const char kExperiment[] = "LowMemoryMargin"; |
59 | 59 |
60 #define EXPERIMENT_CUSTOM_COUNTS(name, sample, min, max, buckets) \ | |
61 { \ | |
62 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, buckets); \ | |
63 if (base::FieldTrialList::TrialExists(kExperiment)) \ | |
64 UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
65 base::FieldTrial::MakeName(name, kExperiment), \ | |
66 sample, min, max, buckets); \ | |
67 } | |
68 | |
69 // Record a size in megabytes, over a potential interval up to 32 GB. | 60 // Record a size in megabytes, over a potential interval up to 32 GB. |
70 #define EXPERIMENT_HISTOGRAM_MEGABYTES(name, sample) \ | 61 #define HISTOGRAM_MEGABYTES(name, sample) \ |
71 EXPERIMENT_CUSTOM_COUNTS(name, sample, 1, 32768, 50) | 62 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 32768, 50) |
72 | 63 |
73 // The default interval in seconds after which to adjust the oom_score_adj | 64 // The default interval in seconds after which to adjust the oom_score_adj |
74 // value. | 65 // value. |
75 const int kAdjustmentIntervalSeconds = 10; | 66 const int kAdjustmentIntervalSeconds = 10; |
76 | 67 |
77 // For each period of this length we record a statistic to indicate whether | 68 // For each period of this length we record a statistic to indicate whether |
78 // or not the user experienced a low memory event. If you change this interval | 69 // or not the user experienced a low memory event. If you change this interval |
79 // you must replace Tabs.Discard.DiscardInLastMinute with a new statistic. | 70 // you must replace Tabs.Discard.DiscardInLastMinute with a new statistic. |
80 const int kRecentTabDiscardIntervalSeconds = 60; | 71 const int kRecentTabDiscardIntervalSeconds = 60; |
81 | 72 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 Browser* browser = *it; | 295 Browser* browser = *it; |
305 TabStripModel* model = browser->tab_strip_model(); | 296 TabStripModel* model = browser->tab_strip_model(); |
306 for (int idx = 0; idx < model->count(); idx++) { | 297 for (int idx = 0; idx < model->count(); idx++) { |
307 // Can't discard tabs that are already discarded or active. | 298 // Can't discard tabs that are already discarded or active. |
308 if (model->IsTabDiscarded(idx) || (model->active_index() == idx)) | 299 if (model->IsTabDiscarded(idx) || (model->active_index() == idx)) |
309 continue; | 300 continue; |
310 WebContents* web_contents = model->GetWebContentsAt(idx); | 301 WebContents* web_contents = model->GetWebContentsAt(idx); |
311 int64 web_contents_id = IdFromWebContents(web_contents); | 302 int64 web_contents_id = IdFromWebContents(web_contents); |
312 if (web_contents_id == target_web_contents_id) { | 303 if (web_contents_id == target_web_contents_id) { |
313 LOG(WARNING) << "Discarding tab " << idx | 304 LOG(WARNING) << "Discarding tab " << idx |
314 << " id " << target_web_contents_id; | 305 << " id " << target_web_contents_id; |
315 // Record statistics before discarding because we want to capture the | 306 // Record statistics before discarding because we want to capture the |
316 // memory state that lead to the discard. | 307 // memory state that lead to the discard. |
317 RecordDiscardStatistics(); | 308 RecordDiscardStatistics(); |
318 model->DiscardWebContentsAt(idx); | 309 model->DiscardWebContentsAt(idx); |
319 recent_tab_discard_ = true; | 310 recent_tab_discard_ = true; |
320 return true; | 311 return true; |
321 } | 312 } |
322 } | 313 } |
323 } | 314 } |
324 return false; | 315 return false; |
325 } | 316 } |
326 | 317 |
327 void OomPriorityManager::RecordDiscardStatistics() { | 318 void OomPriorityManager::RecordDiscardStatistics() { |
328 // Record a raw count so we can compare to discard reloads. | 319 // Record a raw count so we can compare to discard reloads. |
329 discard_count_++; | 320 discard_count_++; |
330 EXPERIMENT_CUSTOM_COUNTS("Tabs.Discard.DiscardCount", | 321 UMA_HISTOGRAM_CUSTOM_COUNTS( |
331 discard_count_, 1, 1000, 50); | 322 "Tabs.Discard.DiscardCount", discard_count_, 1, 1000, 50); |
332 | 323 |
333 // TODO(jamescook): Maybe incorporate extension count? | 324 // TODO(jamescook): Maybe incorporate extension count? |
334 EXPERIMENT_CUSTOM_COUNTS("Tabs.Discard.TabCount", GetTabCount(), 1, 100, 50); | 325 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 326 "Tabs.Discard.TabCount", GetTabCount(), 1, 100, 50); |
335 | 327 |
336 // TODO(jamescook): If the time stats prove too noisy, then divide up users | 328 // TODO(jamescook): If the time stats prove too noisy, then divide up users |
337 // based on how heavily they use Chrome using tab count as a proxy. | 329 // based on how heavily they use Chrome using tab count as a proxy. |
338 // Bin into <= 1, <= 2, <= 4, <= 8, etc. | 330 // Bin into <= 1, <= 2, <= 4, <= 8, etc. |
339 if (last_discard_time_.is_null()) { | 331 if (last_discard_time_.is_null()) { |
340 // This is the first discard this session. | 332 // This is the first discard this session. |
341 TimeDelta interval = TimeTicks::Now() - start_time_; | 333 TimeDelta interval = TimeTicks::Now() - start_time_; |
342 int interval_seconds = static_cast<int>(interval.InSeconds()); | 334 int interval_seconds = static_cast<int>(interval.InSeconds()); |
343 // Record time in seconds over an interval of approximately 1 day. | 335 // Record time in seconds over an interval of approximately 1 day. |
344 EXPERIMENT_CUSTOM_COUNTS( | 336 UMA_HISTOGRAM_CUSTOM_COUNTS( |
345 "Tabs.Discard.InitialTime2", interval_seconds, 1, 100000, 50); | 337 "Tabs.Discard.InitialTime2", interval_seconds, 1, 100000, 50); |
346 } else { | 338 } else { |
347 // Not the first discard, so compute time since last discard. | 339 // Not the first discard, so compute time since last discard. |
348 TimeDelta interval = TimeTicks::Now() - last_discard_time_; | 340 TimeDelta interval = TimeTicks::Now() - last_discard_time_; |
349 int interval_ms = static_cast<int>(interval.InMilliseconds()); | 341 int interval_ms = static_cast<int>(interval.InMilliseconds()); |
350 // Record time in milliseconds over an interval of approximately 1 day. | 342 // Record time in milliseconds over an interval of approximately 1 day. |
351 // Start at 100 ms to get extra resolution in the target 750 ms range. | 343 // Start at 100 ms to get extra resolution in the target 750 ms range. |
352 EXPERIMENT_CUSTOM_COUNTS( | 344 UMA_HISTOGRAM_CUSTOM_COUNTS( |
353 "Tabs.Discard.IntervalTime2", interval_ms, 100, 100000 * 1000, 50); | 345 "Tabs.Discard.IntervalTime2", interval_ms, 100, 100000 * 1000, 50); |
354 } | 346 } |
355 // Record Chrome's concept of system memory usage at the time of the discard. | 347 // Record Chrome's concept of system memory usage at the time of the discard. |
356 base::SystemMemoryInfoKB memory; | 348 base::SystemMemoryInfoKB memory; |
357 if (base::GetSystemMemoryInfo(&memory)) { | 349 if (base::GetSystemMemoryInfo(&memory)) { |
358 // TODO(jamescook): Remove this after R25 is deployed to stable. It does | 350 // TODO(jamescook): Remove this after R25 is deployed to stable. It does |
359 // not have sufficient resolution in the 2-4 GB range and does not properly | 351 // not have sufficient resolution in the 2-4 GB range and does not properly |
360 // account for graphics memory on ARM. Replace with MemAllocatedMB below. | 352 // account for graphics memory on ARM. Replace with MemAllocatedMB below. |
361 int mem_anonymous_mb = (memory.active_anon + memory.inactive_anon) / 1024; | 353 int mem_anonymous_mb = (memory.active_anon + memory.inactive_anon) / 1024; |
362 EXPERIMENT_HISTOGRAM_MEGABYTES("Tabs.Discard.MemAnonymousMB", | 354 HISTOGRAM_MEGABYTES("Tabs.Discard.MemAnonymousMB", mem_anonymous_mb); |
363 mem_anonymous_mb); | |
364 | 355 |
365 // Record graphics GEM object size in a histogram with 50 MB buckets. | 356 // Record graphics GEM object size in a histogram with 50 MB buckets. |
366 int mem_graphics_gem_mb = 0; | 357 int mem_graphics_gem_mb = 0; |
367 if (memory.gem_size != -1) | 358 if (memory.gem_size != -1) |
368 mem_graphics_gem_mb = memory.gem_size / 1024 / 1024; | 359 mem_graphics_gem_mb = memory.gem_size / 1024 / 1024; |
369 RecordLinearHistogram( | 360 RecordLinearHistogram( |
370 "Tabs.Discard.MemGraphicsMB", mem_graphics_gem_mb, 2500, 50); | 361 "Tabs.Discard.MemGraphicsMB", mem_graphics_gem_mb, 2500, 50); |
371 | 362 |
372 // Record shared memory (used by renderer/GPU buffers). | 363 // Record shared memory (used by renderer/GPU buffers). |
373 int mem_shmem_mb = memory.shmem / 1024; | 364 int mem_shmem_mb = memory.shmem / 1024; |
374 RecordLinearHistogram("Tabs.Discard.MemShmemMB", mem_shmem_mb, 2500, 50); | 365 RecordLinearHistogram("Tabs.Discard.MemShmemMB", mem_shmem_mb, 2500, 50); |
375 | 366 |
376 // On Intel, graphics objects are in anonymous pages, but on ARM they are | 367 // On Intel, graphics objects are in anonymous pages, but on ARM they are |
377 // not. For a total "allocated count" add in graphics pages on ARM. | 368 // not. For a total "allocated count" add in graphics pages on ARM. |
378 int mem_allocated_mb = mem_anonymous_mb; | 369 int mem_allocated_mb = mem_anonymous_mb; |
379 #if defined(ARCH_CPU_ARM_FAMILY) | 370 #if defined(ARCH_CPU_ARM_FAMILY) |
380 mem_allocated_mb += mem_graphics_gem_mb; | 371 mem_allocated_mb += mem_graphics_gem_mb; |
381 #endif | 372 #endif |
382 EXPERIMENT_CUSTOM_COUNTS("Tabs.Discard.MemAllocatedMB", mem_allocated_mb, | 373 UMA_HISTOGRAM_CUSTOM_COUNTS( |
383 256, 32768, 50) | 374 "Tabs.Discard.MemAllocatedMB", mem_allocated_mb, 256, 32768, 50); |
384 | 375 |
385 int mem_available_mb = | 376 int mem_available_mb = |
386 (memory.active_file + memory.inactive_file + memory.free) / 1024; | 377 (memory.active_file + memory.inactive_file + memory.free) / 1024; |
387 EXPERIMENT_HISTOGRAM_MEGABYTES("Tabs.Discard.MemAvailableMB", | 378 HISTOGRAM_MEGABYTES("Tabs.Discard.MemAvailableMB", mem_available_mb); |
388 mem_available_mb); | |
389 } | 379 } |
390 // Set up to record the next interval. | 380 // Set up to record the next interval. |
391 last_discard_time_ = TimeTicks::Now(); | 381 last_discard_time_ = TimeTicks::Now(); |
392 } | 382 } |
393 | 383 |
394 void OomPriorityManager::RecordRecentTabDiscard() { | 384 void OomPriorityManager::RecordRecentTabDiscard() { |
395 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 385 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
396 // If we change the interval we need to change the histogram name. | 386 // If we change the interval we need to change the histogram name. |
397 UMA_HISTOGRAM_BOOLEAN("Tabs.Discard.DiscardInLastMinute", | 387 UMA_HISTOGRAM_BOOLEAN("Tabs.Discard.DiscardInLastMinute", |
398 recent_tab_discard_); | 388 recent_tab_discard_); |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore( | 632 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore( |
643 iterator->renderer_handle, score); | 633 iterator->renderer_handle, score); |
644 pid_to_oom_score_[iterator->renderer_handle] = score; | 634 pid_to_oom_score_[iterator->renderer_handle] = score; |
645 } | 635 } |
646 priority += priority_increment; | 636 priority += priority_increment; |
647 } | 637 } |
648 } | 638 } |
649 } | 639 } |
650 | 640 |
651 } // namespace chromeos | 641 } // namespace chromeos |
OLD | NEW |