OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_purger.h" | 5 #include "chrome/browser/memory_purger.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/threading/thread.h" | 9 #include "base/threading/thread.h" |
10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
11 #include "chrome/browser/history/history.h" | 11 #include "chrome/browser/history/history.h" |
12 #include "chrome/browser/profiles/profile_manager.h" | 12 #include "chrome/browser/profiles/profile_manager.h" |
13 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | |
14 #include "chrome/browser/ui/browser_list.h" | 13 #include "chrome/browser/ui/browser_list.h" |
15 #include "chrome/browser/webdata/web_data_service.h" | 14 #include "chrome/browser/webdata/web_data_service.h" |
16 #include "chrome/common/render_messages.h" | 15 #include "chrome/common/render_messages.h" |
17 #include "content/browser/in_process_webkit/webkit_context.h" | 16 #include "content/browser/in_process_webkit/webkit_context.h" |
18 #include "content/browser/renderer_host/backing_store_manager.h" | 17 #include "content/browser/renderer_host/backing_store_manager.h" |
19 #include "content/browser/renderer_host/render_process_host.h" | 18 #include "content/browser/renderer_host/render_process_host.h" |
20 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 19 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
21 #include "content/common/notification_service.h" | 20 #include "content/common/notification_service.h" |
22 #include "net/proxy/proxy_resolver.h" | 21 #include "net/proxy/proxy_resolver.h" |
23 #include "net/proxy/proxy_service.h" | 22 #include "net/proxy/proxy_service.h" |
24 #include "net/url_request/url_request_context.h" | 23 #include "net/url_request/url_request_context.h" |
25 #include "net/url_request/url_request_context_getter.h" | 24 #include "net/url_request/url_request_context_getter.h" |
26 #include "third_party/tcmalloc/chromium/src/google/malloc_extension.h" | 25 #include "third_party/tcmalloc/chromium/src/google/malloc_extension.h" |
27 #include "v8/include/v8.h" | 26 #include "v8/include/v8.h" |
28 | 27 |
29 // PurgeMemoryHelper ----------------------------------------------------------- | 28 // PurgeMemoryHelper ----------------------------------------------------------- |
30 | 29 |
31 // This is a small helper class used to ensure that the objects we want to use | 30 // This is a small helper class used to ensure that the objects we want to use |
32 // on multiple threads are properly refed, so they don't get deleted out from | 31 // on multiple threads are properly refed, so they don't get deleted out from |
33 // under us. | 32 // under us. |
34 class PurgeMemoryIOHelper | 33 class PurgeMemoryIOHelper |
35 : public base::RefCountedThreadSafe<PurgeMemoryIOHelper> { | 34 : public base::RefCountedThreadSafe<PurgeMemoryIOHelper> { |
36 public: | 35 public: |
37 explicit PurgeMemoryIOHelper(SafeBrowsingService* safe_browsing_service) | 36 PurgeMemoryIOHelper() { |
38 : safe_browsing_service_(safe_browsing_service) { | |
39 } | 37 } |
40 | 38 |
41 void AddRequestContextGetter( | 39 void AddRequestContextGetter( |
42 scoped_refptr<net::URLRequestContextGetter> request_context_getter); | 40 scoped_refptr<net::URLRequestContextGetter> request_context_getter); |
43 | 41 |
44 void PurgeMemoryOnIOThread(); | 42 void PurgeMemoryOnIOThread(); |
45 | 43 |
46 private: | 44 private: |
47 typedef scoped_refptr<net::URLRequestContextGetter> RequestContextGetter; | 45 typedef scoped_refptr<net::URLRequestContextGetter> RequestContextGetter; |
48 typedef std::set<RequestContextGetter> RequestContextGetters; | 46 typedef std::set<RequestContextGetter> RequestContextGetters; |
49 | 47 |
50 RequestContextGetters request_context_getters_; | 48 RequestContextGetters request_context_getters_; |
51 scoped_refptr<SafeBrowsingService> safe_browsing_service_; | |
52 | 49 |
53 DISALLOW_COPY_AND_ASSIGN(PurgeMemoryIOHelper); | 50 DISALLOW_COPY_AND_ASSIGN(PurgeMemoryIOHelper); |
54 }; | 51 }; |
55 | 52 |
56 void PurgeMemoryIOHelper::AddRequestContextGetter( | 53 void PurgeMemoryIOHelper::AddRequestContextGetter( |
57 scoped_refptr<net::URLRequestContextGetter> request_context_getter) { | 54 scoped_refptr<net::URLRequestContextGetter> request_context_getter) { |
58 request_context_getters_.insert(request_context_getter); | 55 request_context_getters_.insert(request_context_getter); |
59 } | 56 } |
60 | 57 |
61 void PurgeMemoryIOHelper::PurgeMemoryOnIOThread() { | 58 void PurgeMemoryIOHelper::PurgeMemoryOnIOThread() { |
62 // Ask ProxyServices to purge any memory they can (generally garbage in the | 59 // Ask ProxyServices to purge any memory they can (generally garbage in the |
63 // wrapped ProxyResolver's JS engine). | 60 // wrapped ProxyResolver's JS engine). |
64 for (RequestContextGetters::const_iterator i( | 61 for (RequestContextGetters::const_iterator i( |
65 request_context_getters_.begin()); | 62 request_context_getters_.begin()); |
66 i != request_context_getters_.end(); ++i) | 63 i != request_context_getters_.end(); ++i) |
67 (*i)->GetURLRequestContext()->proxy_service()->PurgeMemory(); | 64 (*i)->GetURLRequestContext()->proxy_service()->PurgeMemory(); |
68 | 65 |
69 // Close the Safe Browsing database, freeing memory used to cache sqlite as | 66 // The appcache and safe browsing services listen for this notification. |
70 // well as a number of in-memory structures. | |
71 safe_browsing_service_->CloseDatabase(); | |
72 | |
73 // The appcache service listens for this notification. | |
74 NotificationService::current()->Notify( | 67 NotificationService::current()->Notify( |
75 NotificationType::PURGE_MEMORY, | 68 NotificationType::PURGE_MEMORY, |
76 Source<void>(NULL), | 69 Source<void>(NULL), |
77 NotificationService::NoDetails()); | 70 NotificationService::NoDetails()); |
78 } | 71 } |
79 | 72 |
80 // ----------------------------------------------------------------------------- | 73 // ----------------------------------------------------------------------------- |
81 | 74 |
82 // static | 75 // static |
83 void MemoryPurger::PurgeAll() { | 76 void MemoryPurger::PurgeAll() { |
84 PurgeBrowser(); | 77 PurgeBrowser(); |
85 PurgeRenderers(); | 78 PurgeRenderers(); |
86 | 79 |
87 // TODO(pkasting): | 80 // TODO(pkasting): |
88 // * Tell the plugin processes to release their free memory? Other stuff? | 81 // * Tell the plugin processes to release their free memory? Other stuff? |
89 // * Enumerate what other processes exist and what to do for them. | 82 // * Enumerate what other processes exist and what to do for them. |
90 } | 83 } |
91 | 84 |
92 // static | 85 // static |
93 void MemoryPurger::PurgeBrowser() { | 86 void MemoryPurger::PurgeBrowser() { |
94 // Dump the backing stores. | 87 // Dump the backing stores. |
95 BackingStoreManager::RemoveAllBackingStores(); | 88 BackingStoreManager::RemoveAllBackingStores(); |
96 | 89 |
97 // Per-profile cleanup. | 90 // Per-profile cleanup. |
98 scoped_refptr<PurgeMemoryIOHelper> purge_memory_io_helper( | 91 scoped_refptr<PurgeMemoryIOHelper> purge_memory_io_helper( |
99 new PurgeMemoryIOHelper(g_browser_process->safe_browsing_service())); | 92 new PurgeMemoryIOHelper()); |
100 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 93 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
101 std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); | 94 std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); |
102 for (size_t i = 0; i < profiles.size(); ++i) { | 95 for (size_t i = 0; i < profiles.size(); ++i) { |
103 purge_memory_io_helper->AddRequestContextGetter( | 96 purge_memory_io_helper->AddRequestContextGetter( |
104 make_scoped_refptr(profiles[i]->GetRequestContext())); | 97 make_scoped_refptr(profiles[i]->GetRequestContext())); |
105 | 98 |
106 // NOTE: Some objects below may be duplicates across profiles. We could | 99 // NOTE: Some objects below may be duplicates across profiles. We could |
107 // conceivably put all these in sets and then iterate over the sets. | 100 // conceivably put all these in sets and then iterate over the sets. |
108 | 101 |
109 // Unload all history backends (freeing memory used to cache sqlite). | 102 // Unload all history backends (freeing memory used to cache sqlite). |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); | 147 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); |
155 !i.IsAtEnd(); i.Advance()) | 148 !i.IsAtEnd(); i.Advance()) |
156 PurgeRendererForHost(i.GetCurrentValue()); | 149 PurgeRendererForHost(i.GetCurrentValue()); |
157 } | 150 } |
158 | 151 |
159 // static | 152 // static |
160 void MemoryPurger::PurgeRendererForHost(RenderProcessHost* host) { | 153 void MemoryPurger::PurgeRendererForHost(RenderProcessHost* host) { |
161 // Direct the renderer to free everything it can. | 154 // Direct the renderer to free everything it can. |
162 host->Send(new ViewMsg_PurgeMemory()); | 155 host->Send(new ViewMsg_PurgeMemory()); |
163 } | 156 } |
OLD | NEW |