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   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.
    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