Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: content/renderer/render_thread_impl.cc

Issue 2391423004: Add UMA for PurgeAndSuspend. (Closed)
Patch Set: Memory.PurgeAndSuspend => PurgeAndSuspend.Memory Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/renderer/render_thread_impl.h ('k') | third_party/WebKit/Source/web/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "content/renderer/render_thread_impl.h" 5 #include "content/renderer/render_thread_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <map> 9 #include <map>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/allocator/allocator_extension.h" 13 #include "base/allocator/allocator_extension.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/debug/crash_logging.h" 15 #include "base/debug/crash_logging.h"
16 #include "base/lazy_instance.h" 16 #include "base/lazy_instance.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/macros.h" 18 #include "base/macros.h"
19 #include "base/memory/discardable_memory_allocator.h" 19 #include "base/memory/discardable_memory_allocator.h"
20 #include "base/memory/memory_coordinator_client_registry.h" 20 #include "base/memory/memory_coordinator_client_registry.h"
21 #include "base/memory/ptr_util.h" 21 #include "base/memory/ptr_util.h"
22 #include "base/memory/shared_memory.h" 22 #include "base/memory/shared_memory.h"
23 #include "base/metrics/field_trial.h" 23 #include "base/metrics/field_trial.h"
24 #include "base/metrics/histogram_macros.h" 24 #include "base/metrics/histogram_macros.h"
25 #include "base/path_service.h" 25 #include "base/path_service.h"
26 #include "base/process/process_metrics.h"
26 #include "base/run_loop.h" 27 #include "base/run_loop.h"
27 #include "base/strings/string16.h" 28 #include "base/strings/string16.h"
28 #include "base/strings/string_number_conversions.h" 29 #include "base/strings/string_number_conversions.h"
29 #include "base/strings/string_split.h" 30 #include "base/strings/string_split.h"
30 #include "base/strings/sys_string_conversions.h" 31 #include "base/strings/sys_string_conversions.h"
31 #include "base/strings/utf_string_conversions.h" 32 #include "base/strings/utf_string_conversions.h"
32 #include "base/threading/simple_thread.h" 33 #include "base/threading/simple_thread.h"
33 #include "base/threading/thread_local.h" 34 #include "base/threading/thread_local.h"
34 #include "base/threading/thread_restrictions.h" 35 #include "base/threading/thread_restrictions.h"
35 #include "base/threading/thread_task_runner_handle.h" 36 #include "base/threading/thread_task_runner_handle.h"
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 #include "content/public/common/service_manager_connection.h" 205 #include "content/public/common/service_manager_connection.h"
205 #include "content/renderer/mus/render_widget_mus_connection.h" 206 #include "content/renderer/mus/render_widget_mus_connection.h"
206 #include "content/renderer/mus/render_widget_window_tree_client_factory.h" 207 #include "content/renderer/mus/render_widget_window_tree_client_factory.h"
207 #include "services/ui/public/cpp/gpu_service.h" 208 #include "services/ui/public/cpp/gpu_service.h"
208 #endif 209 #endif
209 210
210 #if defined(ENABLE_IPC_FUZZER) 211 #if defined(ENABLE_IPC_FUZZER)
211 #include "content/common/external_ipc_dumper.h" 212 #include "content/common/external_ipc_dumper.h"
212 #endif 213 #endif
213 214
215 #if defined(OS_MACOSX)
216 #include <malloc/malloc.h>
217 #else
218 #include <malloc.h>
219 #endif
220
214 using base::ThreadRestrictions; 221 using base::ThreadRestrictions;
215 using blink::WebDocument; 222 using blink::WebDocument;
216 using blink::WebFrame; 223 using blink::WebFrame;
217 using blink::WebNetworkStateNotifier; 224 using blink::WebNetworkStateNotifier;
218 using blink::WebRuntimeFeatures; 225 using blink::WebRuntimeFeatures;
219 using blink::WebScriptController; 226 using blink::WebScriptController;
220 using blink::WebSecurityPolicy; 227 using blink::WebSecurityPolicy;
221 using blink::WebString; 228 using blink::WebString;
222 using blink::WebView; 229 using blink::WebView;
223 using blink::scheduler::WebThreadImplForWorkerScheduler; 230 using blink::scheduler::WebThreadImplForWorkerScheduler;
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 time_zone_monitor->AddClient( 895 time_zone_monitor->AddClient(
889 time_zone_monitor_binding_.CreateInterfacePtrAndBind()); 896 time_zone_monitor_binding_.CreateInterfacePtrAndBind());
890 897
891 #if defined(OS_LINUX) 898 #if defined(OS_LINUX)
892 ChildProcess::current()->SetIOThreadPriority(base::ThreadPriority::DISPLAY); 899 ChildProcess::current()->SetIOThreadPriority(base::ThreadPriority::DISPLAY);
893 ChildThreadImpl::current()->SetThreadPriority( 900 ChildThreadImpl::current()->SetThreadPriority(
894 categorized_worker_pool_->background_worker_thread_id(), 901 categorized_worker_pool_->background_worker_thread_id(),
895 base::ThreadPriority::BACKGROUND); 902 base::ThreadPriority::BACKGROUND);
896 #endif 903 #endif
897 904
905 record_purge_suspend_metric_closure_.Reset(base::Bind(
906 &RenderThreadImpl::RecordPurgeAndSuspendMetrics, base::Unretained(this)));
898 is_renderer_suspended_ = false; 907 is_renderer_suspended_ = false;
899 908
900 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); 909 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
901 } 910 }
902 911
903 RenderThreadImpl::~RenderThreadImpl() { 912 RenderThreadImpl::~RenderThreadImpl() {
904 } 913 }
905 914
906 void RenderThreadImpl::Shutdown() { 915 void RenderThreadImpl::Shutdown() {
907 FOR_EACH_OBSERVER( 916 FOR_EACH_OBSERVER(
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 return handled; 1765 return handled;
1757 } 1766 }
1758 1767
1759 void RenderThreadImpl::OnProcessBackgrounded(bool backgrounded) { 1768 void RenderThreadImpl::OnProcessBackgrounded(bool backgrounded) {
1760 ChildThreadImpl::OnProcessBackgrounded(backgrounded); 1769 ChildThreadImpl::OnProcessBackgrounded(backgrounded);
1761 1770
1762 if (backgrounded) { 1771 if (backgrounded) {
1763 renderer_scheduler_->OnRendererBackgrounded(); 1772 renderer_scheduler_->OnRendererBackgrounded();
1764 } else { 1773 } else {
1765 renderer_scheduler_->OnRendererForegrounded(); 1774 renderer_scheduler_->OnRendererForegrounded();
1775 record_purge_suspend_metric_closure_.Cancel();
1766 is_renderer_suspended_ = false; 1776 is_renderer_suspended_ = false;
1767 } 1777 }
1768 } 1778 }
1769 1779
1770 void RenderThreadImpl::OnProcessPurgeAndSuspend() { 1780 void RenderThreadImpl::OnProcessPurgeAndSuspend() {
1771 ChildThreadImpl::OnProcessPurgeAndSuspend(); 1781 ChildThreadImpl::OnProcessPurgeAndSuspend();
1772 if (is_renderer_suspended_) 1782 if (is_renderer_suspended_)
1773 return; 1783 return;
1774 // TODO(hajimehoshi): Implement purging e.g. cache (crbug/607077) 1784 // TODO(hajimehoshi): Implement purging e.g. cache (crbug/607077)
1775 is_renderer_suspended_ = true; 1785 is_renderer_suspended_ = true;
1776 renderer_scheduler_->SuspendRenderer(); 1786 renderer_scheduler_->SuspendRenderer();
1787
1788 // Since purging is not a synchronouse task (e.g. v8 GC, oilpan GC, ...),
Avi (use Gerrit) 2016/10/17 02:48:04 typo: synchronous
tasak 2016/10/17 04:54:19 Done.
1789 // we need to wait until the task is finished. So wait 15 seconds and
1790 // update purge+suspend UMA histogram.
1791 // TODO(tasak): use MemoryCoordinator's callback to report purge+suspend
1792 // UMA when MemoryCoordinator is available.
1793 GetRendererScheduler()->DefaultTaskRunner()->PostDelayedTask(
1794 FROM_HERE, record_purge_suspend_metric_closure_.callback(),
1795 base::TimeDelta::FromSeconds(15));
1796 }
1797
1798 // TODO(tasak): Replace the following GetMallocUsage() with memory-infra
1799 // when it is possible to run memory-infra without tracing.
1800 #if defined(OS_WIN)
1801 namespace {
1802
1803 static size_t GetMallocUsage() {
1804 DWORD number_of_heaps = ::GetProcessHeaps(0, NULL);
1805 if (number_of_heaps <= 0)
1806 return 0;
1807
1808 size_t malloc_usage = 0;
1809 std::unique_ptr<HANDLE[]> heaps(new HANDLE[number_of_heaps]);
1810 ::GetProcessHeaps(number_of_heaps, heaps.get());
1811 for (unsigned i = 0; i < number_of_heaps; i++) {
Avi (use Gerrit) 2016/10/17 02:48:04 for (HANDLE heap : *heaps) ?
tasak 2016/10/17 04:54:19 Done.
tasak 2016/10/17 10:40:23 I found that it is not possible to use this here b
1812 PROCESS_HEAP_ENTRY heap_entry;
1813 ::HeapLock(heaps[i]);
1814 heap_entry.lpData = NULL;
1815 while (::HeapWalk(heaps[i], &heap_entry) != 0) {
1816 if (heap_entry.lpData == heaps.get())
1817 continue;
1818 if ((heap_entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0)
1819 malloc_usage += heap_entry.cbData;
1820 }
1821 ::HeapUnlock(heaps[i]);
1822 }
1823 return malloc_usage;
1824 }
1825
1826 } // namespace
1827 #elif defined(OS_MACOSX) || defined(OS_IOS)
1828 namespace {
1829
1830 static size_t GetMallocUsage() {
1831 malloc_statistics_t stats = {0};
1832 malloc_zone_statistics(nullptr, &stats);
1833 return stats.size_in_use;
1834 }
1835
1836 } // namespace
1837 #endif
1838
1839 // TODO(tasak): Once it is possible to use memory-infra without tracing,
1840 // we should collect the metrics using memory-infra.
1841 // TODO(tasak): We should also report a difference between the memory usages
1842 // before and after purging by using memory-infra.
1843 void RenderThreadImpl::RecordPurgeAndSuspendMetrics() const {
1844 // If this renderer is resumed, we should not update UMA.
1845 if (!is_renderer_suspended_)
1846 return;
1847
1848 // TODO(tasak): Compare memory metrics between purge-enabled renderers and
1849 // purge-disabled renderers (A/B testing).
1850 blink::WebMemoryStatistics blink_stats = blink::WebMemoryStatistics::Get();
1851 UMA_HISTOGRAM_MEMORY_KB("PurgeAndSuspend.Memory.PartitionAllocKB",
1852 blink_stats.partitionAllocTotalAllocatedBytes / 1024);
1853 UMA_HISTOGRAM_MEMORY_KB("PurgeAndSuspend.Memory.BlinkGCKB",
1854 blink_stats.blinkGCTotalAllocatedBytes / 1024);
1855 #if defined(OS_LINUX) || defined(OS_ANDROID)
1856 struct mallinfo minfo = mallinfo();
1857 #if defined(USE_TCMALLOC)
1858 size_t malloc_usage = minfo.uordblks;
1859 #else
1860 size_t malloc_usage = minfo.hblkhd + minfo.arena;
1861 #endif
1862 #else
1863 size_t malloc_usage = GetMallocUsage();
1864 #endif
1865 UMA_HISTOGRAM_MEMORY_MB("PurgeAndSuspend.Memory.MallocMB",
1866 malloc_usage / 1024 / 1024);
1867
1868 ChildDiscardableSharedMemoryManager::Statistics discardable_stats =
1869 ChildThreadImpl::discardable_shared_memory_manager()->GetStatistics();
1870 size_t discardable_usage =
1871 discardable_stats.total_size - discardable_stats.freelist_size;
1872 UMA_HISTOGRAM_MEMORY_KB("PurgeAndSuspend.Memory.DiscardableKB",
1873 discardable_usage / 1024);
1874
1875 size_t v8_usage = 0;
1876 if (v8::Isolate* isolate = blink::mainThreadIsolate()) {
1877 v8::HeapStatistics v8_heap_statistics;
1878 isolate->GetHeapStatistics(&v8_heap_statistics);
1879 v8_usage = v8_heap_statistics.total_heap_size();
1880 }
1881 // TODO(tasak): Currently only memory usage of mainThreadIsolate() is
1882 // reported. We should collect memory usages of all isolates using
1883 // memory-infra.
1884 UMA_HISTOGRAM_MEMORY_MB("PurgeAndSuspend.Memory.V8MainThreadIsolateMB",
1885 v8_usage / 1024 / 1024);
1886 UMA_HISTOGRAM_MEMORY_MB("PurgeAndSuspend.Memory.TotalAllocatedMB",
1887 (blink_stats.partitionAllocTotalAllocatedBytes +
1888 blink_stats.blinkGCTotalAllocatedBytes +
1889 malloc_usage + v8_usage + discardable_usage) /
1890 1024 / 1024);
1777 } 1891 }
1778 1892
1779 scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync() { 1893 scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync() {
1780 TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync"); 1894 TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync");
1781 1895
1782 if (gpu_channel_) { 1896 if (gpu_channel_) {
1783 // Do nothing if we already have a GPU channel or are already 1897 // Do nothing if we already have a GPU channel or are already
1784 // establishing one. 1898 // establishing one.
1785 if (!gpu_channel_->IsLost()) 1899 if (!gpu_channel_->IsLost())
1786 return gpu_channel_; 1900 return gpu_channel_;
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
2359 } 2473 }
2360 } 2474 }
2361 2475
2362 void RenderThreadImpl::OnRendererInterfaceRequest( 2476 void RenderThreadImpl::OnRendererInterfaceRequest(
2363 mojom::RendererAssociatedRequest request) { 2477 mojom::RendererAssociatedRequest request) {
2364 DCHECK(!renderer_binding_.is_bound()); 2478 DCHECK(!renderer_binding_.is_bound());
2365 renderer_binding_.Bind(std::move(request)); 2479 renderer_binding_.Bind(std::move(request));
2366 } 2480 }
2367 2481
2368 } // namespace content 2482 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/render_thread_impl.h ('k') | third_party/WebKit/Source/web/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698