diff options
author | nasko@chromium.org <nasko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-13 22:39:34 +0000 |
---|---|---|
committer | nasko@chromium.org <nasko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-13 22:39:34 +0000 |
commit | a6381cb574d7e48fd577aab1270d5298a16af6bc (patch) | |
tree | ce8ebd0925be0bc5f8aaee6aba58aadc426c464f /content | |
parent | 5bf2f31639b75587926422d4c3f0a0d523d13cf8 (diff) | |
download | chromium_src-a6381cb574d7e48fd577aab1270d5298a16af6bc.zip chromium_src-a6381cb574d7e48fd577aab1270d5298a16af6bc.tar.gz chromium_src-a6381cb574d7e48fd577aab1270d5298a16af6bc.tar.bz2 |
Adding a command line flag to specify renderer process limit
BUG=111498
TEST=Run chrome with --renderer-process-limit=X where X is the maximum number of renderer processes.
Review URL: http://codereview.chromium.org/9328011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121744 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/browser_main_loop.cc | 11 | ||||
-rw-r--r-- | content/browser/renderer_host/render_process_host_browsertest.cc | 191 | ||||
-rw-r--r-- | content/browser/renderer_host/render_process_host_browsertest.h | 10 | ||||
-rw-r--r-- | content/browser/renderer_host/render_process_host_impl.cc | 28 | ||||
-rw-r--r-- | content/public/browser/render_process_host.h | 10 | ||||
-rw-r--r-- | content/public/common/content_switches.cc | 5 | ||||
-rw-r--r-- | content/public/common/content_switches.h | 1 |
7 files changed, 152 insertions, 104 deletions
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index c953db0..4096821 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -11,6 +11,7 @@ #include "base/message_loop.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" +#include "base/string_number_conversions.h" #include "base/threading/thread_restrictions.h" #include "content/browser/browser_thread_impl.h" #include "content/browser/download/download_file_manager.h" @@ -26,6 +27,7 @@ #include "content/public/browser/browser_main_parts.h" #include "content/public/browser/browser_shutdown.h" #include "content/public/browser/content_browser_client.h" +#include "content/public/browser/render_process_host.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" #include "content/public/common/result_codes.h" @@ -271,6 +273,15 @@ void BrowserMainLoop::EarlyInitialization() { if (parsed_command_line_.HasSwitch(switches::kEnableTcpFastOpen)) net::set_tcp_fastopen_enabled(true); + if (parsed_command_line_.HasSwitch(switches::kRendererProcessLimit)) { + std::string limit_string = parsed_command_line_.GetSwitchValueASCII( + switches::kRendererProcessLimit); + size_t process_limit; + if (base::StringToSizeT(limit_string, &process_limit)) { + content::RenderProcessHost::SetMaxRendererProcessCount(process_limit); + } + } + if (parts_.get()) parts_->PostEarlyInitialization(); } diff --git a/content/browser/renderer_host/render_process_host_browsertest.cc b/content/browser/renderer_host/render_process_host_browsertest.cc index 4d4676d..50de340 100644 --- a/content/browser/renderer_host/render_process_host_browsertest.cc +++ b/content/browser/renderer_host/render_process_host_browsertest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -55,9 +55,103 @@ base::ProcessHandle RenderProcessHostTest::ShowSingletonTab(const GURL& page) { return wc->GetRenderProcessHost()->GetHandle(); } +void RenderProcessHostTestWithCommandLine::SetUpCommandLine( + CommandLine* command_line) { + InProcessBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII(switches::kRendererProcessLimit, "1"); +} + +// When we hit the max number of renderers, verify that the way we do process +// sharing behaves correctly. In particular, this test is verifying that even +// when we hit the max process limit, that renderers of each type will wind up +// in a process of that type, even if that means creating a new process. +void RenderProcessHostTest::TestProcessOverflow() { + int tab_count = 1; + int host_count = 1; + WebContents* tab1 = NULL; + WebContents* tab2 = NULL; + content::RenderProcessHost* rph1 = NULL; + content::RenderProcessHost* rph2 = NULL; + content::RenderProcessHost* rph3 = NULL; + +#if defined(USE_VIRTUAL_KEYBOARD) + ++host_count; // For the virtual keyboard. +#endif + + // Change the first tab to be the new tab page (TYPE_WEBUI). + GURL newtab(chrome::kTestNewTabURL); + ui_test_utils::NavigateToURL(browser(), newtab); + EXPECT_EQ(tab_count, browser()->tab_count()); + tab1 = browser()->GetWebContentsAt(tab_count - 1); + rph1 = tab1->GetRenderProcessHost(); + EXPECT_EQ(tab1->GetURL(), newtab); + EXPECT_EQ(host_count, RenderProcessHostCount()); + + // Create a new TYPE_TABBED tab. It should be in its own process. + GURL page1("data:text/html,hello world1"); + browser()->ShowSingletonTab(page1); + if (browser()->tab_count() == tab_count) + ui_test_utils::WaitForNewTab(browser()); + tab_count++; + host_count++; + EXPECT_EQ(tab_count, browser()->tab_count()); + tab1 = browser()->GetWebContentsAt(tab_count - 1); + rph2 = tab1->GetRenderProcessHost(); + EXPECT_EQ(tab1->GetURL(), page1); + EXPECT_EQ(host_count, RenderProcessHostCount()); + EXPECT_NE(rph1, rph2); + + // Create another TYPE_TABBED tab. It should share the previous process. + GURL page2("data:text/html,hello world2"); + browser()->ShowSingletonTab(page2); + if (browser()->tab_count() == tab_count) + ui_test_utils::WaitForNewTab(browser()); + tab_count++; + EXPECT_EQ(tab_count, browser()->tab_count()); + tab2 = browser()->GetWebContentsAt(tab_count - 1); + EXPECT_EQ(tab2->GetURL(), page2); + EXPECT_EQ(host_count, RenderProcessHostCount()); + EXPECT_EQ(tab2->GetRenderProcessHost(), rph2); + + // Create another TYPE_WEBUI tab. It should share the process with newtab. + // Note: intentionally create this tab after the TYPE_TABBED tabs to exercise + // bug 43448 where extension and WebUI tabs could get combined into normal + // renderers. + GURL history(chrome::kTestHistoryURL); + browser()->ShowSingletonTab(history); + if (browser()->tab_count() == tab_count) + ui_test_utils::WaitForNewTab(browser()); + tab_count++; + EXPECT_EQ(tab_count, browser()->tab_count()); + tab2 = browser()->GetWebContentsAt(tab_count - 1); + EXPECT_EQ(tab2->GetURL(), history); + EXPECT_EQ(host_count, RenderProcessHostCount()); + EXPECT_EQ(tab2->GetRenderProcessHost(), rph1); + + // Create a TYPE_EXTENSION tab. It should be in its own process. + // (the bookmark manager is implemented as an extension) + GURL bookmarks(chrome::kTestBookmarksURL); + browser()->ShowSingletonTab(bookmarks); + if (browser()->tab_count() == tab_count) + ui_test_utils::WaitForNewTab(browser()); + tab_count++; +#if !defined(USE_VIRTUAL_KEYBOARD) + // The virtual keyboard already creates an extension process. So this + // should not increase the process count. + host_count++; +#endif + EXPECT_EQ(tab_count, browser()->tab_count()); + tab1 = browser()->GetWebContentsAt(tab_count - 1); + rph3 = tab1->GetRenderProcessHost(); + EXPECT_EQ(tab1->GetURL(), bookmarks); + EXPECT_EQ(host_count, RenderProcessHostCount()); + EXPECT_NE(rph1, rph3); + EXPECT_NE(rph2, rph3); +} + IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, ProcessPerTab) { // Set max renderers to 1 to force running out of processes. - content::RenderProcessHost::SetMaxRendererProcessCountForTest(1); + content::RenderProcessHost::SetMaxRendererProcessCount(1); CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); parsed_command_line.AppendSwitch(switches::kProcessPerTab); @@ -147,93 +241,14 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, Backgrounding) { } #endif -// When we hit the max number of renderers, verify that the way we do process -// sharing behaves correctly. In particular, this test is verifying that even -// when we hit the max process limit, that renderers of each type will wind up -// in a process of that type, even if that means creating a new process. IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, ProcessOverflow) { // Set max renderers to 1 to force running out of processes. - content::RenderProcessHost::SetMaxRendererProcessCountForTest(1); - - int tab_count = 1; - int host_count = 1; - WebContents* tab1 = NULL; - WebContents* tab2 = NULL; - content::RenderProcessHost* rph1 = NULL; - content::RenderProcessHost* rph2 = NULL; - content::RenderProcessHost* rph3 = NULL; - -#if defined(USE_VIRTUAL_KEYBOARD) - ++host_count; // For the virtual keyboard. -#endif - - // Change the first tab to be the new tab page (TYPE_WEBUI). - GURL newtab(chrome::kTestNewTabURL); - ui_test_utils::NavigateToURL(browser(), newtab); - EXPECT_EQ(tab_count, browser()->tab_count()); - tab1 = browser()->GetWebContentsAt(tab_count - 1); - rph1 = tab1->GetRenderProcessHost(); - EXPECT_EQ(tab1->GetURL(), newtab); - EXPECT_EQ(host_count, RenderProcessHostCount()); - - // Create a new TYPE_TABBED tab. It should be in its own process. - GURL page1("data:text/html,hello world1"); - browser()->ShowSingletonTab(page1); - if (browser()->tab_count() == tab_count) - ui_test_utils::WaitForNewTab(browser()); - tab_count++; - host_count++; - EXPECT_EQ(tab_count, browser()->tab_count()); - tab1 = browser()->GetWebContentsAt(tab_count - 1); - rph2 = tab1->GetRenderProcessHost(); - EXPECT_EQ(tab1->GetURL(), page1); - EXPECT_EQ(host_count, RenderProcessHostCount()); - EXPECT_NE(rph1, rph2); - - // Create another TYPE_TABBED tab. It should share the previous process. - GURL page2("data:text/html,hello world2"); - browser()->ShowSingletonTab(page2); - if (browser()->tab_count() == tab_count) - ui_test_utils::WaitForNewTab(browser()); - tab_count++; - EXPECT_EQ(tab_count, browser()->tab_count()); - tab2 = browser()->GetWebContentsAt(tab_count - 1); - EXPECT_EQ(tab2->GetURL(), page2); - EXPECT_EQ(host_count, RenderProcessHostCount()); - EXPECT_EQ(tab2->GetRenderProcessHost(), rph2); - - // Create another TYPE_WEBUI tab. It should share the process with newtab. - // Note: intentionally create this tab after the TYPE_TABBED tabs to exercise - // bug 43448 where extension and WebUI tabs could get combined into normal - // renderers. - GURL history(chrome::kTestHistoryURL); - browser()->ShowSingletonTab(history); - if (browser()->tab_count() == tab_count) - ui_test_utils::WaitForNewTab(browser()); - tab_count++; - EXPECT_EQ(tab_count, browser()->tab_count()); - tab2 = browser()->GetWebContentsAt(tab_count - 1); - EXPECT_EQ(tab2->GetURL(), history); - EXPECT_EQ(host_count, RenderProcessHostCount()); - EXPECT_EQ(tab2->GetRenderProcessHost(), rph1); + content::RenderProcessHost::SetMaxRendererProcessCount(1); + TestProcessOverflow(); +} - // Create a TYPE_EXTENSION tab. It should be in its own process. - // (the bookmark manager is implemented as an extension) - GURL bookmarks(chrome::kTestBookmarksURL); - browser()->ShowSingletonTab(bookmarks); - if (browser()->tab_count() == tab_count) - ui_test_utils::WaitForNewTab(browser()); - tab_count++; -#if !defined(USE_VIRTUAL_KEYBOARD) - // The virtual keyboard already creates an extension process. So this - // should not increase the process count. - host_count++; -#endif - EXPECT_EQ(tab_count, browser()->tab_count()); - tab1 = browser()->GetWebContentsAt(tab_count - 1); - rph3 = tab1->GetRenderProcessHost(); - EXPECT_EQ(tab1->GetURL(), bookmarks); - EXPECT_EQ(host_count, RenderProcessHostCount()); - EXPECT_NE(rph1, rph3); - EXPECT_NE(rph2, rph3); +// Variation of the ProcessOverflow test, which is driven through command line +// parameter instead of direct function call into the class. +IN_PROC_BROWSER_TEST_F(RenderProcessHostTestWithCommandLine, ProcessOverflow) { + TestProcessOverflow(); } diff --git a/content/browser/renderer_host/render_process_host_browsertest.h b/content/browser/renderer_host/render_process_host_browsertest.h index 58d9f51..13cd7c7 100644 --- a/content/browser/renderer_host/render_process_host_browsertest.h +++ b/content/browser/renderer_host/render_process_host_browsertest.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,8 +6,10 @@ #define CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_BROWSERTEST_H_ #pragma once +#include "base/command_line.h" #include "base/process.h" #include "chrome/test/base/in_process_browser_test.h" +#include "content/public/common/content_switches.h" class GURL; @@ -18,6 +20,12 @@ class RenderProcessHostTest : public InProcessBrowserTest { int RenderProcessHostCount(); base::ProcessHandle ShowSingletonTab(const GURL& page); + void TestProcessOverflow(); +}; + +class RenderProcessHostTestWithCommandLine : public RenderProcessHostTest { + protected: + virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE; }; #endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_BROWSERTEST_H_ diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index f4682e1..55f6313 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -202,11 +202,20 @@ class RendererURLRequestContextSelector scoped_refptr<net::URLRequestContextGetter> media_request_context_; }; -size_t max_renderer_count_override = 0; +// the global list of all renderer processes +base::LazyInstance<IDMap<content::RenderProcessHost> >::Leaky + g_all_hosts = LAZY_INSTANCE_INITIALIZER; -size_t GetMaxRendererProcessCount() { - if (max_renderer_count_override) - return max_renderer_count_override; +} // namespace + +// Stores the maximum number of renderer processes the content module can +// create. +static size_t g_max_renderer_count_override = 0; + +// static +size_t content::RenderProcessHost::GetMaxRendererProcessCount() { + if (g_max_renderer_count_override) + return g_max_renderer_count_override; // Defines the maximum number of renderer processes according to the // amount of installed memory as reported by the OS. The table @@ -246,19 +255,12 @@ size_t GetMaxRendererProcessCount() { return max_count; } -// the global list of all renderer processes -base::LazyInstance<IDMap<content::RenderProcessHost> >::Leaky - g_all_hosts = LAZY_INSTANCE_INITIALIZER; - -} // namespace - // static bool g_run_renderer_in_process_ = false; // static -void content::RenderProcessHost::SetMaxRendererProcessCountForTest( - size_t count) { - max_renderer_count_override = count; +void content::RenderProcessHost::SetMaxRendererProcessCount(size_t count) { + g_max_renderer_count_override = count; } RenderProcessHostImpl::RenderProcessHostImpl( diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index 785a484..adb08728 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h @@ -220,9 +220,15 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Message::Sender, content::BrowserContext* browser_context, const GURL& site_url); // Overrides the default heuristic for limiting the max renderer process - // count. This is useful for unit testing process limit behaviors. + // count. This is useful for unit testing process limit behaviors. It is + // also used to allow a command line parameter to configure the max number of + // renderer processes and should only be called once during startup. // A value of zero means to use the default heuristic. - static void SetMaxRendererProcessCountForTest(size_t count); + static void SetMaxRendererProcessCount(size_t count); + + // Returns the current max number of renderer processes used by the content + // module. + static size_t GetMaxRendererProcessCount(); }; } // namespace content. diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 0bec7fa..bcbdf11 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc @@ -495,6 +495,11 @@ const char kRendererCrashTest[] = "renderer-crash-test"; // Causes the process to run as renderer instead of as browser. const char kRendererProcess[] = "renderer"; +// Overrides the default/calculated limit to the number of renderer processes. +// Very high values for this setting can lead to high memory/resource usage +// or instability. +const char kRendererProcessLimit[] = "renderer-process-limit"; + // Causes the renderer process to display a dialog on launch. const char kRendererStartupDialog[] = "renderer-startup-dialog"; diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index f271ebd..0937325 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -151,6 +151,7 @@ CONTENT_EXPORT extern const char kRendererAssertTest[]; extern const char kRendererCmdPrefix[]; CONTENT_EXPORT extern const char kRendererCrashTest[]; CONTENT_EXPORT extern const char kRendererProcess[]; +extern const char kRendererProcessLimit[]; extern const char kRendererStartupDialog[]; // TODO(jam): this doesn't belong in content. CONTENT_EXPORT extern const char kServiceProcess[]; |