memory_details.h revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// Use of this source code is governed by a BSD-style license that can be
3363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// found in the LICENSE file.
4363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
5363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#ifndef CHROME_BROWSER_MEMORY_DETAILS_H_
6363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#define CHROME_BROWSER_MEMORY_DETAILS_H_
7363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
8363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <vector>
9363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
10363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "base/process_util.h"
11363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "base/ref_counted.h"
12363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "chrome/common/child_process_info.h"
13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// We collect data about each browser process.  A browser may
15363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// have multiple processes (of course!).  Even IE has multiple
16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// processes these days.
17363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstruct ProcessMemoryInformation {
18363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  ProcessMemoryInformation()
190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger      : pid(0),
20363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        num_processes(0),
21363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        is_diagnostics(false),
22363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        type(ChildProcessInfo::UNKNOWN_PROCESS) {
23363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  }
24363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
25363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // The process id.
26363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  base::ProcessId pid;
27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // The working set information.
28363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  base::WorkingSetKBytes working_set;
29363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // The committed bytes.
30363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  base::CommittedKBytes committed;
31363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // The process version
32363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  std::wstring version;
33363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // The process product name.
34363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  std::wstring product_name;
35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // The number of processes which this memory represents.
36363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  int num_processes;
37363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // A process is a diagnostics process if it is rendering
38363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // about:xxx information.
39363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  bool is_diagnostics;
40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // If this is a child process of Chrome, what type (i.e. plugin) it is.
41363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  ChildProcessInfo::ProcessType type;
42363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // A collection of titles used, i.e. for a tab it'll show all the page titles.
43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  std::vector<std::wstring> titles;
44363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger};
45363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
46363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergertypedef std::vector<ProcessMemoryInformation> ProcessMemoryInformationList;
47363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
48363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// Browser Process Information.
49363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstruct ProcessData {
50363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  std::wstring name;
51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  std::wstring process_name;
52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  ProcessMemoryInformationList processes;
53363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger};
54363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
55363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#if defined(OS_MACOSX)
56363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerclass ProcessInfoSnapshot;
57363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif
58363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
59363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// MemoryDetails fetches memory details about current running browsers.
60363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// Because this data can only be fetched asynchronously, callers use
61363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// this class via a callback.
62363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//
63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// Example usage:
64363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//
65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//    class MyMemoryDetailConsumer : public MemoryDetails {
66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//
67363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//      MyMemoryDetailConsumer() {
68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//        // Anything but |StartFetch()|.
69363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//      }
70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//
71363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//      // (Or just call |StartFetch()| explicitly if there's nothing else to
72363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//      // do.)
73363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//      void StartDoingStuff() {
74363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//        StartFetch();  // Starts fetching details.
75363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//        // Etc.
76363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//      }
77363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//
78363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//      // Your other class stuff here
79363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//
80363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//      virtual void OnDetailsAvailable() {
81363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//        // do work with memory info here
82363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//      }
83363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger//    }
84363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerclass MemoryDetails : public base::RefCountedThreadSafe<MemoryDetails> {
85363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger public:
86363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // Constructor.
87363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  MemoryDetails();
88363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
89363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // Access to the process detail information.  This data is only available
90363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // after OnDetailsAvailable() has been called.
91363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  const std::vector<ProcessData>& processes() { return process_data_; }
92363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
93363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  // Initiate updating the current memory details.  These are fetched
94  // asynchronously because data must be collected from multiple threads.
95  // OnDetailsAvailable will be called when this process is complete.
96  void StartFetch();
97
98  virtual void OnDetailsAvailable() {}
99
100 protected:
101  friend class base::RefCountedThreadSafe<MemoryDetails>;
102
103  virtual ~MemoryDetails() {}
104
105 private:
106  // Collect child process information on the IO thread.  This is needed because
107  // information about some child process types (i.e. plugins) can only be taken
108  // on that thread.  The data will be used by about:memory.  When finished,
109  // invokes back to the file thread to run the rest of the about:memory
110  // functionality.
111  void CollectChildInfoOnIOThread();
112
113  // Collect current process information from the OS and store it
114  // for processing.  If data has already been collected, clears old
115  // data and re-collects the data.
116  // Note - this function enumerates memory details from many processes
117  // and is fairly expensive to run, hence it's run on the file thread.
118  // The parameter holds information about processes from the IO thread.
119  void CollectProcessData(std::vector<ProcessMemoryInformation>);
120
121#if defined(OS_MACOSX)
122  // A helper for |CollectProcessData()|, collecting data on the Chrome/Chromium
123  // process with PID |pid|. The collected data is added to the state of the
124  // object (in |process_data_|).
125  void CollectProcessDataChrome(
126      const std::vector<ProcessMemoryInformation>& child_info,
127      base::ProcessId pid,
128      const ProcessInfoSnapshot& process_info);
129#endif
130
131  // Collect child process information on the UI thread.  Information about
132  // renderer processes is only available there.
133  void CollectChildInfoOnUIThread();
134
135  // Each time we take a memory sample, we do a little work to update
136  // the global histograms for tracking memory usage.
137  void UpdateHistograms();
138
139  // Returns a pointer to the ProcessData structure for Chrome.
140  ProcessData* ChromeBrowser();
141
142  std::vector<ProcessData> process_data_;
143
144  DISALLOW_COPY_AND_ASSIGN(MemoryDetails);
145};
146
147#endif  // CHROME_BROWSER_MEMORY_DETAILS_H_
148