| 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 |