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

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

Issue 2350423003: [Tentaive patch for discussion] Add Purge+Suspend metrics as UMA.
Patch Set: Add UMA to tab_manager 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/ptr_util.h" 20 #include "base/memory/ptr_util.h"
21 #include "base/memory/shared_memory.h" 21 #include "base/memory/shared_memory.h"
22 #include "base/metrics/field_trial.h" 22 #include "base/metrics/field_trial.h"
23 #include "base/metrics/histogram_macros.h" 23 #include "base/metrics/histogram_macros.h"
24 #include "base/path_service.h" 24 #include "base/path_service.h"
25 #include "base/process/process_metrics.h"
25 #include "base/run_loop.h" 26 #include "base/run_loop.h"
26 #include "base/strings/string16.h" 27 #include "base/strings/string16.h"
27 #include "base/strings/string_number_conversions.h" 28 #include "base/strings/string_number_conversions.h"
28 #include "base/strings/string_split.h" 29 #include "base/strings/string_split.h"
29 #include "base/strings/sys_string_conversions.h" 30 #include "base/strings/sys_string_conversions.h"
30 #include "base/strings/utf_string_conversions.h" 31 #include "base/strings/utf_string_conversions.h"
31 #include "base/threading/simple_thread.h" 32 #include "base/threading/simple_thread.h"
32 #include "base/threading/thread_local.h" 33 #include "base/threading/thread_local.h"
33 #include "base/threading/thread_restrictions.h" 34 #include "base/threading/thread_restrictions.h"
34 #include "base/threading/thread_task_runner_handle.h" 35 #include "base/threading/thread_task_runner_handle.h"
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 #include "content/public/common/mojo_shell_connection.h" 205 #include "content/public/common/mojo_shell_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 #include <malloc.h>
216
214 using base::ThreadRestrictions; 217 using base::ThreadRestrictions;
215 using blink::WebDocument; 218 using blink::WebDocument;
216 using blink::WebFrame; 219 using blink::WebFrame;
217 using blink::WebNetworkStateNotifier; 220 using blink::WebNetworkStateNotifier;
218 using blink::WebRuntimeFeatures; 221 using blink::WebRuntimeFeatures;
219 using blink::WebScriptController; 222 using blink::WebScriptController;
220 using blink::WebSecurityPolicy; 223 using blink::WebSecurityPolicy;
221 using blink::WebString; 224 using blink::WebString;
222 using blink::WebView; 225 using blink::WebView;
223 using blink::scheduler::WebThreadImplForWorkerScheduler; 226 using blink::scheduler::WebThreadImplForWorkerScheduler;
(...skipping 1506 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 } else { 1733 } else {
1731 renderer_scheduler_->OnRendererForegrounded(); 1734 renderer_scheduler_->OnRendererForegrounded();
1732 is_renderer_suspended_ = false; 1735 is_renderer_suspended_ = false;
1733 } 1736 }
1734 } 1737 }
1735 1738
1736 void RenderThreadImpl::OnProcessPurgeAndSuspend() { 1739 void RenderThreadImpl::OnProcessPurgeAndSuspend() {
1737 ChildThreadImpl::OnProcessPurgeAndSuspend(); 1740 ChildThreadImpl::OnProcessPurgeAndSuspend();
1738 if (is_renderer_suspended_) 1741 if (is_renderer_suspended_)
1739 return; 1742 return;
1740 // TODO(hajimehoshi): Implement purging e.g. cache (crbug/607077) 1743
1744 // If PurgeAndSuspendFeature is disabled, do nothing except updating UMA.
1745 // The data is used as "Force Disabled" metric.
1746 if (base::FeatureList::IsEnabled(features::kPurgeAndSuspend)) {
1747 // TODO(tasak): use MemoryCoordinator instead of NotifyMemoryPressure.
1748 base::MemoryPressureListener::NotifyMemoryPressure(
1749 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
1750 base::allocator::ReleaseFreeMemory();
1751
1752 renderer_scheduler_->SuspendRenderer();
1753 }
1741 is_renderer_suspended_ = true; 1754 is_renderer_suspended_ = true;
1742 renderer_scheduler_->SuspendRenderer(); 1755
1756 // Since purging is not a synchronouse task (e.g. v8 GC, oilpan GC, ...),
1757 // we need to wait until the task is finished. So wait 5 seconds and
1758 // update purge+suspend UMA histogram.
1759 // TODO(tasak): use MemoryCoordinator's callback to report purge+suspend
1760 // UMA when MemoryCoordinator is available.
1761 GetRendererScheduler()->DefaultTaskRunner()->PostDelayedTask(
1762 FROM_HERE,
1763 base::Bind(&RenderThreadImpl::OnDumpMemoryUsage, base::Unretained(this)),
1764 base::TimeDelta::FromSeconds(15));
Sami 2016/09/28 16:01:08 What if the renderer is unsuspended before this ta
tasak 2016/09/29 02:37:51 OnDumpMemoryUsage checks is_renderer_suspended. So
1765 }
1766
1767 // TODO(tasak): Replace the following GetMallocUsage() with memory-infra
1768 // when it is possible to run memory-infra without tracing.
1769 #if defined(OS_WIN)
1770 namespace {
1771
1772 class ScopedHeapLock {
1773 public:
1774 explicit ScopedHeapLock(HANDLE handle) : handle_(handle) {
1775 ::HeapLock(handle_);
1776 }
1777 ~ScopedHeapLock() { ::HeapUnlock(handle_); }
1778
1779 private:
1780 ScopedHeapLock() = delete;
1781 ScopedHeapLock(const ScopedHeapLock&) = delete;
1782
1783 HANDLE handle_;
1784 };
1785
1786 static size_t GetMallocUsage() {
1787 DWORD number_of_heaps = ::GetProcessHeaps(0, NULL);
1788 if (number_of_heaps <= 0)
1789 return 0;
1790
1791 size_t malloc_usage = 0;
1792 std::unique_ptr<HANDLE[]> heaps(new HANDLE[number_of_heaps]);
1793 ::GetProcessHeaps(number_of_heaps, heaps.get());
1794 for (unsigned i = 0; i < number_of_heaps; i++) {
1795 PROCESS_HEAP_ENTRY heap_entry;
1796 heap_entry.lpData = NULL;
1797 {
1798 ScopedHeapLock lock(heaps[i]);
1799 while (::HeapWalk(heaps[i], &heap_entry) != 0) {
1800 if (heap_entry.lpData == heaps.get())
1801 continue;
1802 if ((heap_entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0)
1803 malloc_usage += heap_entry.cbData;
1804 }
1805 }
1806 }
1807 return malloc_usage;
1808 }
1809
1810 } // namespace
1811 #endif
1812
1813 #if defined(OS_MACOSX) || defined(OS_IOS)
1814 namespace {
1815
1816 static size_t GetMallocUsage() {
1817 malloc_statistics_t stats = {0};
1818 malloc_zone_statistics(nullptr, &stats);
1819 return stats.size_in_use;
1820 }
1821
1822 } // namespace
1823 #endif
1824
1825 // For purge+suspend, report memory usage diff by using UMA_HISTOGRAM.
1826 void RenderThreadImpl::OnDumpMemoryUsage() const {
1827 // If this renderer is resumed, we should not update UMA.
1828 if (!is_renderer_suspended_)
1829 return;
1830
1831 // TODO(tasak): firstly we are trying to compare metrics from enabled and
1832 // disabled renderers (A/B testing). However we also need to gather
1833 // metrics which measures how many memory usages are reduced.
1834 blink::WebMemoryStatistics blink_stats = blink::WebMemoryStatistics::Get();
1835 UMA_HISTOGRAM_MEMORY_KB("Memory.PurgeAndSuspend.PartitionAllocKB",
1836 blink_stats.partitionAllocTotalAllocatedBytes);
1837 UMA_HISTOGRAM_MEMORY_KB("Memory.PurgeAndSuspend.BlinkGCKB",
1838 blink_stats.blinkGCTotalAllocatedBytes);
1839 #if defined(OS_LINUX) || defined(OS_ANDROID)
1840 struct mallinfo minfo = mallinfo();
1841 #if defined(USE_TCMALLOC)
1842 size_t malloc_usage = minfo.uordblks;
1843 #else
1844 size_t malloc_usage = minfo.hblkhd + minfo.arena;
1845 #endif
1846 #else
1847 size_t malloc_usage = GetMallocUsage();
1848 #endif
1849 UMA_HISTOGRAM_MEMORY_KB("Memory.PurgeAndSuspend.MallocKB", malloc_usage);
1850
1851 ChildDiscardableSharedMemoryManager::Statistics discardable_stats =
1852 ChildThreadImpl::discardable_shared_memory_manager()->GetStatistics();
1853 size_t discardable_usage =
1854 discardable_stats.total_size - discardable_stats.freelist_size;
1855 UMA_HISTOGRAM_MEMORY_KB("Memory.PurgeAndSuspend.DiscardableKB",
1856 discardable_usage);
1857
1858 size_t v8_usage = 0;
1859 if (v8::Isolate* isolate = blink::mainThreadIsolate()) {
1860 v8::HeapStatistics v8_heap_statistics;
1861 isolate->GetHeapStatistics(&v8_heap_statistics);
1862 v8_usage = v8_heap_statistics.total_heap_size();
1863 }
1864 UMA_HISTOGRAM_MEMORY_KB("Memory.PurgeAndSuspend.V8MainThreadIsolateKB",
1865 v8_usage);
1866 UMA_HISTOGRAM_MEMORY_KB("Memory.PurgeAndSuspend.TotalAllocatedKB",
1867 blink_stats.partitionAllocTotalAllocatedBytes +
1868 blink_stats.blinkGCTotalAllocatedBytes +
1869 malloc_usage + v8_usage + discardable_usage);
1743 } 1870 }
1744 1871
1745 void RenderThreadImpl::OnCreateNewFrame(FrameMsg_NewFrame_Params params) { 1872 void RenderThreadImpl::OnCreateNewFrame(FrameMsg_NewFrame_Params params) {
1746 // Debug cases of https://crbug.com/626802. 1873 // Debug cases of https://crbug.com/626802.
1747 base::debug::SetCrashKeyValue("newframe_routing_id", 1874 base::debug::SetCrashKeyValue("newframe_routing_id",
1748 base::IntToString(params.routing_id)); 1875 base::IntToString(params.routing_id));
1749 base::debug::SetCrashKeyValue("newframe_proxy_id", 1876 base::debug::SetCrashKeyValue("newframe_proxy_id",
1750 base::IntToString(params.proxy_routing_id)); 1877 base::IntToString(params.proxy_routing_id));
1751 base::debug::SetCrashKeyValue("newframe_opener_id", 1878 base::debug::SetCrashKeyValue("newframe_opener_id",
1752 base::IntToString(params.opener_routing_id)); 1879 base::IntToString(params.opener_routing_id));
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 if (blink::mainThreadIsolate()) { 2419 if (blink::mainThreadIsolate()) {
2293 blink::mainThreadIsolate()->MemoryPressureNotification( 2420 blink::mainThreadIsolate()->MemoryPressureNotification(
2294 v8::MemoryPressureLevel::kCritical); 2421 v8::MemoryPressureLevel::kCritical);
2295 blink::MemoryPressureNotificationToWorkerThreadIsolates( 2422 blink::MemoryPressureNotificationToWorkerThreadIsolates(
2296 v8::MemoryPressureLevel::kCritical); 2423 v8::MemoryPressureLevel::kCritical);
2297 } 2424 }
2298 } 2425 }
2299 2426
2300 2427
2301 } // namespace content 2428 } // 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