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