| 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 "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> |
| (...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 GetConnector()->BindInterface(mojom::kBrowserServiceName, | 896 GetConnector()->BindInterface(mojom::kBrowserServiceName, |
| 897 mojo::MakeRequest(&storage_partition_service_)); | 897 mojo::MakeRequest(&storage_partition_service_)); |
| 898 | 898 |
| 899 #if defined(OS_LINUX) | 899 #if defined(OS_LINUX) |
| 900 ChildProcess::current()->SetIOThreadPriority(base::ThreadPriority::DISPLAY); | 900 ChildProcess::current()->SetIOThreadPriority(base::ThreadPriority::DISPLAY); |
| 901 ChildThreadImpl::current()->SetThreadPriority( | 901 ChildThreadImpl::current()->SetThreadPriority( |
| 902 categorized_worker_pool_->background_worker_thread_id(), | 902 categorized_worker_pool_->background_worker_thread_id(), |
| 903 base::ThreadPriority::BACKGROUND); | 903 base::ThreadPriority::BACKGROUND); |
| 904 #endif | 904 #endif |
| 905 | 905 |
| 906 record_purge_suspend_growth_metric_closure_.Reset( | 906 process_foregrounded_count_ = 0; |
| 907 base::Bind(&RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics, | |
| 908 base::Unretained(this))); | |
| 909 needs_to_record_first_active_paint_ = false; | 907 needs_to_record_first_active_paint_ = false; |
| 910 | 908 |
| 911 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); | 909 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); |
| 912 | 910 |
| 913 // If this renderer doesn't run inside the browser process, enable | 911 // If this renderer doesn't run inside the browser process, enable |
| 914 // SequencedWorkerPool. Otherwise, it should already have been enabled. | 912 // SequencedWorkerPool. Otherwise, it should already have been enabled. |
| 915 // TODO(fdoray): Remove this once the SequencedWorkerPool to TaskScheduler | 913 // TODO(fdoray): Remove this once the SequencedWorkerPool to TaskScheduler |
| 916 // redirection experiment concludes https://crbug.com/622400. | 914 // redirection experiment concludes https://crbug.com/622400. |
| 917 if (!command_line.HasSwitch(switches::kSingleProcess)) | 915 if (!command_line.HasSwitch(switches::kSingleProcess)) |
| 918 base::SequencedWorkerPool::EnableForProcess(); | 916 base::SequencedWorkerPool::EnableForProcess(); |
| (...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1652 } | 1650 } |
| 1653 | 1651 |
| 1654 void RenderThreadImpl::OnProcessBackgrounded(bool backgrounded) { | 1652 void RenderThreadImpl::OnProcessBackgrounded(bool backgrounded) { |
| 1655 ChildThreadImpl::OnProcessBackgrounded(backgrounded); | 1653 ChildThreadImpl::OnProcessBackgrounded(backgrounded); |
| 1656 | 1654 |
| 1657 if (backgrounded) { | 1655 if (backgrounded) { |
| 1658 renderer_scheduler_->OnRendererBackgrounded(); | 1656 renderer_scheduler_->OnRendererBackgrounded(); |
| 1659 needs_to_record_first_active_paint_ = false; | 1657 needs_to_record_first_active_paint_ = false; |
| 1660 } else { | 1658 } else { |
| 1661 renderer_scheduler_->OnRendererForegrounded(); | 1659 renderer_scheduler_->OnRendererForegrounded(); |
| 1662 | 1660 process_foregrounded_count_++; |
| 1663 record_purge_suspend_growth_metric_closure_.Cancel(); | |
| 1664 record_purge_suspend_growth_metric_closure_.Reset( | |
| 1665 base::Bind(&RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics, | |
| 1666 base::Unretained(this))); | |
| 1667 } | 1661 } |
| 1668 } | 1662 } |
| 1669 | 1663 |
| 1670 void RenderThreadImpl::OnProcessPurgeAndSuspend() { | 1664 void RenderThreadImpl::OnProcessPurgeAndSuspend() { |
| 1671 ChildThreadImpl::OnProcessPurgeAndSuspend(); | 1665 ChildThreadImpl::OnProcessPurgeAndSuspend(); |
| 1672 if (!RendererIsHidden()) | 1666 if (!RendererIsHidden()) |
| 1673 return; | 1667 return; |
| 1674 | 1668 |
| 1675 if (!base::FeatureList::IsEnabled(features::kPurgeAndSuspend)) | 1669 if (!base::FeatureList::IsEnabled(features::kPurgeAndSuspend)) |
| 1676 return; | 1670 return; |
| 1677 | 1671 |
| 1678 base::MemoryCoordinatorClientRegistry::GetInstance()->PurgeMemory(); | 1672 base::MemoryCoordinatorClientRegistry::GetInstance()->PurgeMemory(); |
| 1679 needs_to_record_first_active_paint_ = true; | 1673 needs_to_record_first_active_paint_ = true; |
| 1680 | 1674 |
| 1681 RendererMemoryMetrics memory_metrics; | 1675 RendererMemoryMetrics memory_metrics; |
| 1682 if (!GetRendererMemoryMetrics(&memory_metrics)) | 1676 if (!GetRendererMemoryMetrics(&memory_metrics)) |
| 1683 return; | 1677 return; |
| 1684 | 1678 |
| 1685 purge_and_suspend_memory_metrics_ = memory_metrics; | 1679 purge_and_suspend_memory_metrics_ = memory_metrics; |
| 1686 // record how many memory usage increases after purged. | 1680 // record how many memory usage increases after purged. |
| 1681 // Since RenderThreadImpl is kept alive while its render process is alive, |
| 1682 // it is possible to use base::Unretained(this) here. |
| 1687 GetRendererScheduler()->DefaultTaskRunner()->PostDelayedTask( | 1683 GetRendererScheduler()->DefaultTaskRunner()->PostDelayedTask( |
| 1688 FROM_HERE, record_purge_suspend_growth_metric_closure_.callback(), | 1684 FROM_HERE, |
| 1689 base::TimeDelta::FromMinutes(5)); | 1685 base::Bind(&RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics, |
| 1686 base::Unretained(this), "30min", process_foregrounded_count_), |
| 1687 base::TimeDelta::FromMinutes(30)); |
| 1690 GetRendererScheduler()->DefaultTaskRunner()->PostDelayedTask( | 1688 GetRendererScheduler()->DefaultTaskRunner()->PostDelayedTask( |
| 1691 FROM_HERE, record_purge_suspend_growth_metric_closure_.callback(), | 1689 FROM_HERE, |
| 1692 base::TimeDelta::FromMinutes(10)); | 1690 base::Bind(&RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics, |
| 1691 base::Unretained(this), "60min", process_foregrounded_count_), |
| 1692 base::TimeDelta::FromMinutes(60)); |
| 1693 GetRendererScheduler()->DefaultTaskRunner()->PostDelayedTask( | 1693 GetRendererScheduler()->DefaultTaskRunner()->PostDelayedTask( |
| 1694 FROM_HERE, record_purge_suspend_growth_metric_closure_.callback(), | 1694 FROM_HERE, |
| 1695 base::TimeDelta::FromMinutes(15)); | 1695 base::Bind(&RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics, |
| 1696 base::Unretained(this), "90min", process_foregrounded_count_), |
| 1697 base::TimeDelta::FromMinutes(90)); |
| 1696 } | 1698 } |
| 1697 | 1699 |
| 1698 // TODO(tasak): Replace the following GetMallocUsage() with memory-infra | 1700 // TODO(tasak): Replace the following GetMallocUsage() with memory-infra |
| 1699 // when it is possible to run memory-infra without tracing. | 1701 // when it is possible to run memory-infra without tracing. |
| 1700 #if defined(OS_WIN) | 1702 #if defined(OS_WIN) |
| 1701 namespace { | 1703 namespace { |
| 1702 | 1704 |
| 1703 static size_t GetMallocUsage() { | 1705 static size_t GetMallocUsage() { |
| 1704 // Iterate through whichever heap the CRT is using. | 1706 // Iterate through whichever heap the CRT is using. |
| 1705 HANDLE crt_heap = reinterpret_cast<HANDLE>(_get_heap_handle()); | 1707 HANDLE crt_heap = reinterpret_cast<HANDLE>(_get_heap_handle()); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1787 total_allocated / render_view_count / 1024 / 1024; | 1789 total_allocated / render_view_count / 1024 / 1024; |
| 1788 | 1790 |
| 1789 return true; | 1791 return true; |
| 1790 } | 1792 } |
| 1791 | 1793 |
| 1792 #define GET_MEMORY_GROWTH(current, previous, allocator) \ | 1794 #define GET_MEMORY_GROWTH(current, previous, allocator) \ |
| 1793 (current.allocator > previous.allocator \ | 1795 (current.allocator > previous.allocator \ |
| 1794 ? current.allocator - previous.allocator \ | 1796 ? current.allocator - previous.allocator \ |
| 1795 : 0) | 1797 : 0) |
| 1796 | 1798 |
| 1797 void RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics() const { | 1799 #define UMA_HISTOGRAM_MEMORY_GROWTH_KB(basename, suffix, memory_usage) \ |
| 1800 { \ |
| 1801 std::string histogram_name = \ |
| 1802 base::StringPrintf("%s.%s", basename, suffix); \ |
| 1803 UMA_HISTOGRAM_MEMORY_KB(histogram_name, memory_usage); \ |
| 1804 } |
| 1805 |
| 1806 void RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics( |
| 1807 const char* suffix, |
| 1808 int foregrounded_count_when_purged) { |
| 1798 // If this renderer is resumed, we should not update UMA. | 1809 // If this renderer is resumed, we should not update UMA. |
| 1799 if (!RendererIsHidden()) | 1810 if (!RendererIsHidden()) |
| 1800 return; | 1811 return; |
| 1812 if (foregrounded_count_when_purged != process_foregrounded_count_) |
| 1813 return; |
| 1801 | 1814 |
| 1802 RendererMemoryMetrics memory_metrics; | 1815 RendererMemoryMetrics memory_metrics; |
| 1803 if (!GetRendererMemoryMetrics(&memory_metrics)) | 1816 if (!GetRendererMemoryMetrics(&memory_metrics)) |
| 1804 return; | 1817 return; |
| 1805 | 1818 |
| 1806 UMA_HISTOGRAM_MEMORY_KB( | 1819 UMA_HISTOGRAM_MEMORY_GROWTH_KB( |
| 1807 "PurgeAndSuspend.Experimental.MemoryGrowth.PartitionAllocKB", | 1820 "PurgeAndSuspend.Experimental.MemoryGrowth.PartitionAllocKB", suffix, |
| 1808 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, | 1821 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, |
| 1809 partition_alloc_kb)); | 1822 partition_alloc_kb)); |
| 1810 UMA_HISTOGRAM_MEMORY_KB( | 1823 UMA_HISTOGRAM_MEMORY_GROWTH_KB( |
| 1811 "PurgeAndSuspend.Experimental.MemoryGrowth.BlinkGCKB", | 1824 "PurgeAndSuspend.Experimental.MemoryGrowth.BlinkGCKB", suffix, |
| 1812 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, | 1825 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, |
| 1813 blink_gc_kb)); | 1826 blink_gc_kb)); |
| 1814 UMA_HISTOGRAM_MEMORY_KB( | 1827 UMA_HISTOGRAM_MEMORY_GROWTH_KB( |
| 1815 "PurgeAndSuspend.Experimental.MemoryGrowth.MallocKB", | 1828 "PurgeAndSuspend.Experimental.MemoryGrowth.MallocKB", suffix, |
| 1816 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, | 1829 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, |
| 1817 malloc_mb) * 1024); | 1830 malloc_mb) * |
| 1818 UMA_HISTOGRAM_MEMORY_KB( | 1831 1024); |
| 1819 "PurgeAndSuspend.Experimental.MemoryGrowth.DiscardableKB", | 1832 UMA_HISTOGRAM_MEMORY_GROWTH_KB( |
| 1833 "PurgeAndSuspend.Experimental.MemoryGrowth.DiscardableKB", suffix, |
| 1820 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, | 1834 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, |
| 1821 discardable_kb)); | 1835 discardable_kb)); |
| 1822 UMA_HISTOGRAM_MEMORY_KB( | 1836 UMA_HISTOGRAM_MEMORY_GROWTH_KB( |
| 1823 "PurgeAndSuspend.Experimental.MemoryGrowth.V8MainThreadIsolateKB", | 1837 "PurgeAndSuspend.Experimental.MemoryGrowth.V8MainThreadIsolateKB", suffix, |
| 1824 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, | 1838 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, |
| 1825 v8_main_thread_isolate_mb) * 1024); | 1839 v8_main_thread_isolate_mb) * |
| 1826 UMA_HISTOGRAM_MEMORY_KB( | 1840 1024); |
| 1827 "PurgeAndSuspend.Experimental.MemoryGrowth.TotalAllocatedKB", | 1841 UMA_HISTOGRAM_MEMORY_GROWTH_KB( |
| 1842 "PurgeAndSuspend.Experimental.MemoryGrowth.TotalAllocatedKB", suffix, |
| 1828 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, | 1843 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_, |
| 1829 total_allocated_mb) * 1024); | 1844 total_allocated_mb) * |
| 1845 1024); |
| 1830 } | 1846 } |
| 1831 | 1847 |
| 1832 scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync() { | 1848 scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync() { |
| 1833 TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync"); | 1849 TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync"); |
| 1834 | 1850 |
| 1835 if (gpu_channel_) { | 1851 if (gpu_channel_) { |
| 1836 // Do nothing if we already have a GPU channel or are already | 1852 // Do nothing if we already have a GPU channel or are already |
| 1837 // establishing one. | 1853 // establishing one. |
| 1838 if (!gpu_channel_->IsLost()) | 1854 if (!gpu_channel_->IsLost()) |
| 1839 return gpu_channel_; | 1855 return gpu_channel_; |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2442 } | 2458 } |
| 2443 } | 2459 } |
| 2444 | 2460 |
| 2445 void RenderThreadImpl::OnRendererInterfaceRequest( | 2461 void RenderThreadImpl::OnRendererInterfaceRequest( |
| 2446 mojom::RendererAssociatedRequest request) { | 2462 mojom::RendererAssociatedRequest request) { |
| 2447 DCHECK(!renderer_binding_.is_bound()); | 2463 DCHECK(!renderer_binding_.is_bound()); |
| 2448 renderer_binding_.Bind(std::move(request)); | 2464 renderer_binding_.Bind(std::move(request)); |
| 2449 } | 2465 } |
| 2450 | 2466 |
| 2451 } // namespace content | 2467 } // namespace content |
| OLD | NEW |