| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/memory_details.h" | 5 #include "chrome/browser/memory_details.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 // This operation will hit no fewer than 3 threads. | 126 // This operation will hit no fewer than 3 threads. |
| 127 // | 127 // |
| 128 // The BrowserChildProcessHostIterator can only be accessed from the IO thread. | 128 // The BrowserChildProcessHostIterator can only be accessed from the IO thread. |
| 129 // | 129 // |
| 130 // The RenderProcessHostIterator can only be accessed from the UI thread. | 130 // The RenderProcessHostIterator can only be accessed from the UI thread. |
| 131 // | 131 // |
| 132 // This operation can take 30-100ms to complete. We never want to have | 132 // This operation can take 30-100ms to complete. We never want to have |
| 133 // one task run for that long on the UI or IO threads. So, we run the | 133 // one task run for that long on the UI or IO threads. So, we run the |
| 134 // expensive parts of this operation over on the blocking pool. | 134 // expensive parts of this operation over on the blocking pool. |
| 135 // | 135 // |
| 136 void MemoryDetails::StartFetch(CollectionMode mode) { | 136 void MemoryDetails::StartFetch() { |
| 137 // This might get called from the UI or FILE threads, but should not be | 137 // This might get called from the UI or FILE threads, but should not be |
| 138 // getting called from the IO thread. | 138 // getting called from the IO thread. |
| 139 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); | 139 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 140 | 140 |
| 141 // In order to process this request, we need to use the plugin information. | 141 // In order to process this request, we need to use the plugin information. |
| 142 // However, plugin process information is only available from the IO thread. | 142 // However, plugin process information is only available from the IO thread. |
| 143 BrowserThread::PostTask( | 143 BrowserThread::PostTask( |
| 144 BrowserThread::IO, FROM_HERE, | 144 BrowserThread::IO, FROM_HERE, |
| 145 base::Bind(&MemoryDetails::CollectChildInfoOnIOThread, this, mode)); | 145 base::Bind(&MemoryDetails::CollectChildInfoOnIOThread, this)); |
| 146 } | 146 } |
| 147 | 147 |
| 148 MemoryDetails::~MemoryDetails() {} | 148 MemoryDetails::~MemoryDetails() {} |
| 149 | 149 |
| 150 std::string MemoryDetails::ToLogString() { | 150 std::string MemoryDetails::ToLogString() { |
| 151 std::string log; | 151 std::string log; |
| 152 log.reserve(4096); | 152 log.reserve(4096); |
| 153 ProcessMemoryInformationList processes = ChromeBrowser()->processes; | 153 ProcessMemoryInformationList processes = ChromeBrowser()->processes; |
| 154 // Sort by memory consumption, low to high. | 154 // Sort by memory consumption, low to high. |
| 155 std::sort(processes.begin(), processes.end()); | 155 std::sort(processes.begin(), processes.end()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 176 static_cast<int>(iter1->working_set.shared) / 1024); | 176 static_cast<int>(iter1->working_set.shared) / 1024); |
| 177 #if defined(OS_CHROMEOS) | 177 #if defined(OS_CHROMEOS) |
| 178 log += StringPrintf(", %d MB swapped", | 178 log += StringPrintf(", %d MB swapped", |
| 179 static_cast<int>(iter1->working_set.swapped) / 1024); | 179 static_cast<int>(iter1->working_set.swapped) / 1024); |
| 180 #endif | 180 #endif |
| 181 log += "\n"; | 181 log += "\n"; |
| 182 } | 182 } |
| 183 return log; | 183 return log; |
| 184 } | 184 } |
| 185 | 185 |
| 186 void MemoryDetails::CollectChildInfoOnIOThread(CollectionMode mode) { | 186 void MemoryDetails::CollectChildInfoOnIOThread() { |
| 187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 188 | 188 |
| 189 std::vector<ProcessMemoryInformation> child_info; | 189 std::vector<ProcessMemoryInformation> child_info; |
| 190 | 190 |
| 191 // Collect the list of child processes. A 0 |handle| means that | 191 // Collect the list of child processes. A 0 |handle| means that |
| 192 // the process is being launched, so we skip it. | 192 // the process is being launched, so we skip it. |
| 193 for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) { | 193 for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) { |
| 194 ProcessMemoryInformation info; | 194 ProcessMemoryInformation info; |
| 195 if (!iter.GetData().handle) | 195 if (!iter.GetData().handle) |
| 196 continue; | 196 continue; |
| 197 info.pid = base::GetProcId(iter.GetData().handle); | 197 info.pid = base::GetProcId(iter.GetData().handle); |
| 198 if (!info.pid) | 198 if (!info.pid) |
| 199 continue; | 199 continue; |
| 200 | 200 |
| 201 info.process_type = iter.GetData().process_type; | 201 info.process_type = iter.GetData().process_type; |
| 202 info.renderer_type = ProcessMemoryInformation::RENDERER_UNKNOWN; | 202 info.renderer_type = ProcessMemoryInformation::RENDERER_UNKNOWN; |
| 203 info.titles.push_back(iter.GetData().name); | 203 info.titles.push_back(iter.GetData().name); |
| 204 child_info.push_back(info); | 204 child_info.push_back(info); |
| 205 } | 205 } |
| 206 | 206 |
| 207 // Now go do expensive memory lookups on the blocking pool. | 207 // Now go do expensive memory lookups on the blocking pool. |
| 208 BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior( | 208 BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior( |
| 209 FROM_HERE, | 209 FROM_HERE, |
| 210 base::Bind(&MemoryDetails::CollectProcessData, this, mode, child_info), | 210 base::Bind(&MemoryDetails::CollectProcessData, this, child_info), |
| 211 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); | 211 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); |
| 212 } | 212 } |
| 213 | 213 |
| 214 void MemoryDetails::CollectChildInfoOnUIThread() { | 214 void MemoryDetails::CollectChildInfoOnUIThread() { |
| 215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 216 ProcessData* const chrome_browser = ChromeBrowser(); | 216 ProcessData* const chrome_browser = ChromeBrowser(); |
| 217 | 217 |
| 218 // First pass, collate the widgets by process ID. | 218 // First pass, collate the widgets by process ID. |
| 219 std::map<base::ProcessId, std::vector<RenderWidgetHost*>> widgets_by_pid; | 219 std::map<base::ProcessId, std::vector<RenderWidgetHost*>> widgets_by_pid; |
| 220 scoped_ptr<content::RenderWidgetHostIterator> widget_it( | 220 scoped_ptr<content::RenderWidgetHostIterator> widget_it( |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 // Get rid of other Chrome processes that are from a different profile. | 344 // Get rid of other Chrome processes that are from a different profile. |
| 345 auto is_unknown = [](ProcessMemoryInformation& process) { | 345 auto is_unknown = [](ProcessMemoryInformation& process) { |
| 346 return process.process_type == content::PROCESS_TYPE_UNKNOWN; | 346 return process.process_type == content::PROCESS_TYPE_UNKNOWN; |
| 347 }; | 347 }; |
| 348 auto& vector = chrome_browser->processes; | 348 auto& vector = chrome_browser->processes; |
| 349 vector.erase(std::remove_if(vector.begin(), vector.end(), is_unknown), | 349 vector.erase(std::remove_if(vector.begin(), vector.end(), is_unknown), |
| 350 vector.end()); | 350 vector.end()); |
| 351 | 351 |
| 352 OnDetailsAvailable(); | 352 OnDetailsAvailable(); |
| 353 } | 353 } |
| OLD | NEW |