1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
|
// Copyright (c) 2012 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.
#ifndef CHROME_BROWSER_MEMORY_DETAILS_H_
#define CHROME_BROWSER_MEMORY_DETAILS_H_
#include <map>
#include <vector>
#include "base/memory/ref_counted.h"
#include "base/process/process_handle.h"
#include "base/process/process_metrics.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "chrome/browser/site_details.h"
#include "content/public/common/process_type.h"
// We collect data about each browser process. A browser may
// have multiple processes (of course!). Even IE has multiple
// processes these days.
struct ProcessMemoryInformation {
// NOTE: Do not remove or reorder the elements in this enum, and only add new
// items at the end. We depend on these specific values in a histogram.
enum RendererProcessType {
RENDERER_UNKNOWN = 0,
RENDERER_NORMAL,
RENDERER_CHROME, // WebUI (chrome:// URL)
RENDERER_EXTENSION, // chrome-extension://
RENDERER_DEVTOOLS, // Web inspector
RENDERER_INTERSTITIAL, // malware/phishing interstitial
RENDERER_BACKGROUND_APP // hosted app background page
};
static std::string GetRendererTypeNameInEnglish(RendererProcessType type);
static std::string GetFullTypeNameInEnglish(
int process_type,
RendererProcessType rtype);
ProcessMemoryInformation();
~ProcessMemoryInformation();
// Default ordering is by private memory consumption.
bool operator<(const ProcessMemoryInformation& rhs) const;
// The process id.
base::ProcessId pid;
// The working set information.
base::WorkingSetKBytes working_set;
// The committed bytes.
base::CommittedKBytes committed;
// The process version
base::string16 version;
// The process product name.
base::string16 product_name;
// The number of processes which this memory represents.
int num_processes;
// A process is a diagnostics process if it is rendering about:memory.
// Mark this specially so that it can avoid counting it in its own
// results.
bool is_diagnostics;
// If this is a child process of Chrome, what type (i.e. plugin) it is.
int process_type;
// If this is a renderer process, what type it is.
RendererProcessType renderer_type;
// A collection of titles used, i.e. for a tab it'll show all the page titles.
std::vector<base::string16> titles;
};
typedef std::vector<ProcessMemoryInformation> ProcessMemoryInformationList;
// Browser Process Information.
struct ProcessData {
ProcessData();
ProcessData(const ProcessData& rhs);
~ProcessData();
ProcessData& operator=(const ProcessData& rhs);
base::string16 name;
base::string16 process_name;
ProcessMemoryInformationList processes;
// Track site data for predicting process counts with out-of-process iframes.
// See site_details.h.
BrowserContextSiteDataMap site_data;
};
// MemoryGrowthTracker tracks latest metrics about record time and memory usage
// at that time per process.
class MemoryGrowthTracker {
public:
MemoryGrowthTracker();
~MemoryGrowthTracker();
// If 30 minutes have passed since last UMA record, UpdateSample() computes
// a difference between current memory usage |sample| of process |pid| and
// stored memory usage at the time of last UMA record. Then, it updates the
// stored memory usage to |sample|, stores the difference in |diff| and
// returns true.
// If no memory usage of |pid| has not been recorded so far or 30 minutes
// have not passed since last record, it just returns false.
// |sample| is memory usage in kB.
bool UpdateSample(base::ProcessId pid, int sample, int* diff);
private:
// Latest metrics about record time and memory usage at that time per process.
// The second values of |memory_sizes_| are in kB.
std::map<base::ProcessId, base::TimeTicks> times_;
std::map<base::ProcessId, int> memory_sizes_;
DISALLOW_COPY_AND_ASSIGN(MemoryGrowthTracker);
};
#if defined(OS_MACOSX)
class ProcessInfoSnapshot;
#endif
// MemoryDetails fetches memory details about current running browsers.
// Because this data can only be fetched asynchronously, callers use
// this class via a callback.
//
// Example usage:
//
// class MyMemoryDetailConsumer : public MemoryDetails {
//
// MyMemoryDetailConsumer() {
// // Anything but |StartFetch()|.
// }
//
// // (Or just call |StartFetch()| explicitly if there's nothing else to
// // do.)
// void StartDoingStuff() {
// StartFetch(); // Starts fetching details.
// // Etc.
// }
//
// // Your other class stuff here
//
// virtual void OnDetailsAvailable() {
// // do work with memory info here
// }
// }
class MemoryDetails : public base::RefCountedThreadSafe<MemoryDetails> {
public:
enum UserMetricsMode {
UPDATE_USER_METRICS, // Update UMA memory histograms with results.
SKIP_USER_METRICS
};
// Constructor.
MemoryDetails();
// Access to the process detail information. This data is only available
// after OnDetailsAvailable() has been called.
const std::vector<ProcessData>& processes() { return process_data_; }
// Initiate updating the current memory details. These are fetched
// asynchronously because data must be collected from multiple threads.
// Updates UMA memory histograms if |mode| is UPDATE_USER_METRICS.
// OnDetailsAvailable will be called when this process is complete.
void StartFetch(UserMetricsMode user_metrics_mode);
virtual void OnDetailsAvailable() = 0;
// Returns a string summarizing memory usage of the Chrome browser process
// and all sub-processes, suitable for logging.
std::string ToLogString();
protected:
friend class base::RefCountedThreadSafe<MemoryDetails>;
virtual ~MemoryDetails();
// Set MemoryGrowthTracker into MemoryDetails.
void SetMemoryGrowthTracker(MemoryGrowthTracker* memory_growth_tracker);
private:
// Collect child process information on the IO thread. This is needed because
// information about some child process types (i.e. plugins) can only be taken
// on that thread. The data will be used by about:memory. When finished,
// invokes back to the file thread to run the rest of the about:memory
// functionality.
void CollectChildInfoOnIOThread();
// Collect current process information from the OS and store it
// for processing. If data has already been collected, clears old
// data and re-collects the data.
// Note - this function enumerates memory details from many processes
// and is fairly expensive to run, hence it's run on the file thread.
// The parameter holds information about processes from the IO thread.
void CollectProcessData(const std::vector<ProcessMemoryInformation>&);
#if defined(OS_MACOSX)
// A helper for |CollectProcessData()|, collecting data on the Chrome/Chromium
// process with PID |pid|. The collected data is added to the state of the
// object (in |process_data_|).
void CollectProcessDataChrome(
const std::vector<ProcessMemoryInformation>& child_info,
base::ProcessId pid,
const ProcessInfoSnapshot& process_info);
#endif
// Collect child process information on the UI thread. Information about
// renderer processes is only available there.
void CollectChildInfoOnUIThread();
// Updates the global histograms for tracking memory usage.
void UpdateHistograms();
#if defined(OS_CHROMEOS)
void UpdateSwapHistograms();
#endif
// Returns a pointer to the ProcessData structure for Chrome.
ProcessData* ChromeBrowser();
std::vector<ProcessData> process_data_;
UserMetricsMode user_metrics_mode_;
// A pointer to MemoryGrowthTracker which is contained in a longer-lived
// owner of MemoryDetails, for example, ChromeMetricsServiceClient.
// The pointer is NULL by default and set by SetMemoryGrowthTracker().
// If it is NULL, nothing is tracked.
MemoryGrowthTracker* memory_growth_tracker_;
#if defined(OS_CHROMEOS)
base::SwapInfo swap_info_;
#endif
DISALLOW_COPY_AND_ASSIGN(MemoryDetails);
};
#endif // CHROME_BROWSER_MEMORY_DETAILS_H_
|