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 string16 version; 52 // The process product name. 53 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<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 string16 name; 78 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 #if defined(OS_CHROMEOS) 91 struct SwapData { 92 SwapData() 93 : num_reads(0), 94 num_writes(0), 95 compr_data_size(0), 96 orig_data_size(0), 97 mem_used_total(0) { 98 } 99 100 uint64 num_reads; 101 uint64 num_writes; 102 uint64 compr_data_size; 103 uint64 orig_data_size; 104 uint64 mem_used_total; 105 }; 106 #endif 107 108 // MemoryDetails fetches memory details about current running browsers. 109 // Because this data can only be fetched asynchronously, callers use 110 // this class via a callback. 111 // 112 // Example usage: 113 // 114 // class MyMemoryDetailConsumer : public MemoryDetails { 115 // 116 // MyMemoryDetailConsumer() { 117 // // Anything but |StartFetch()|. 118 // } 119 // 120 // // (Or just call |StartFetch()| explicitly if there's nothing else to 121 // // do.) 122 // void StartDoingStuff() { 123 // StartFetch(); // Starts fetching details. 124 // // Etc. 125 // } 126 // 127 // // Your other class stuff here 128 // 129 // virtual void OnDetailsAvailable() { 130 // // do work with memory info here 131 // } 132 // } 133 class MemoryDetails : public base::RefCountedThreadSafe<MemoryDetails> { 134 public: 135 enum UserMetricsMode { 136 UPDATE_USER_METRICS, // Update UMA memory histograms with results. 137 SKIP_USER_METRICS 138 }; 139 140 // Constructor. 141 MemoryDetails(); 142 143 // Access to the process detail information. This data is only available 144 // after OnDetailsAvailable() has been called. 145 const std::vector<ProcessData>& processes() { return process_data_; } 146 147 // Initiate updating the current memory details. These are fetched 148 // asynchronously because data must be collected from multiple threads. 149 // Updates UMA memory histograms if |mode| is UPDATE_USER_METRICS. 150 // OnDetailsAvailable will be called when this process is complete. 151 void StartFetch(UserMetricsMode user_metrics_mode); 152 153 virtual void OnDetailsAvailable() = 0; 154 155 // Returns a string summarizing memory usage of the Chrome browser process 156 // and all sub-processes, suitable for logging. 157 std::string ToLogString(); 158 159 protected: 160 friend class base::RefCountedThreadSafe<MemoryDetails>; 161 162 virtual ~MemoryDetails(); 163 164 private: 165 // Collect child process information on the IO thread. This is needed because 166 // information about some child process types (i.e. plugins) can only be taken 167 // on that thread. The data will be used by about:memory. When finished, 168 // invokes back to the file thread to run the rest of the about:memory 169 // functionality. 170 void CollectChildInfoOnIOThread(); 171 172 // Collect current process information from the OS and store it 173 // for processing. If data has already been collected, clears old 174 // data and re-collects the data. 175 // Note - this function enumerates memory details from many processes 176 // and is fairly expensive to run, hence it's run on the file thread. 177 // The parameter holds information about processes from the IO thread. 178 void CollectProcessData(const std::vector<ProcessMemoryInformation>&); 179 180 #if defined(OS_MACOSX) 181 // A helper for |CollectProcessData()|, collecting data on the Chrome/Chromium 182 // process with PID |pid|. The collected data is added to the state of the 183 // object (in |process_data_|). 184 void CollectProcessDataChrome( 185 const std::vector<ProcessMemoryInformation>& child_info, 186 base::ProcessId pid, 187 const ProcessInfoSnapshot& process_info); 188 #endif 189 190 // Collect child process information on the UI thread. Information about 191 // renderer processes is only available there. 192 void CollectChildInfoOnUIThread(); 193 194 // Updates the global histograms for tracking memory usage. 195 void UpdateHistograms(); 196 197 #if defined(OS_CHROMEOS) 198 void UpdateSwapHistograms(); 199 #endif 200 201 // Returns a pointer to the ProcessData structure for Chrome. 202 ProcessData* ChromeBrowser(); 203 204 std::vector<ProcessData> process_data_; 205 206 UserMetricsMode user_metrics_mode_; 207 208 #if defined(OS_CHROMEOS) 209 SwapData swap_data_; 210 #endif 211 212 DISALLOW_COPY_AND_ASSIGN(MemoryDetails); 213 }; 214 215 #endif // CHROME_BROWSER_MEMORY_DETAILS_H_ 216