Home | History | Annotate | Download | only in browser
      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