mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 805855 - Free dirty pages in response to all memory-pressure messages. r=jlebar
This commit is contained in:
parent
31446e19f7
commit
3dbabca27a
@ -587,3 +587,7 @@ pref("general.useragent.override.facebook.com", "\(Mobile#(Android; Mobile");
|
|||||||
pref("general.useragent.override.youtube.com", "\(Mobile#(Android; Mobile");
|
pref("general.useragent.override.youtube.com", "\(Mobile#(Android; Mobile");
|
||||||
|
|
||||||
pref("jsloader.reuseGlobal", true);
|
pref("jsloader.reuseGlobal", true);
|
||||||
|
|
||||||
|
// Enable freeing dirty pages when minimizing memory; this reduces memory
|
||||||
|
// consumption when applications are sent to the background.
|
||||||
|
pref("memory.free_dirty_pages", true);
|
||||||
|
@ -3810,6 +3810,9 @@ pref("memory.low_memory_notification_interval_ms", 10000);
|
|||||||
// window to be collected via the GC/CC.
|
// window to be collected via the GC/CC.
|
||||||
pref("memory.ghost_window_timeout_seconds", 60);
|
pref("memory.ghost_window_timeout_seconds", 60);
|
||||||
|
|
||||||
|
// Disable freeing dirty pages when minimizing memory.
|
||||||
|
pref("memory.free_dirty_pages", false);
|
||||||
|
|
||||||
pref("social.enabled", false);
|
pref("social.enabled", false);
|
||||||
|
|
||||||
// Disable idle observer fuzz, because only privileged content can access idle
|
// Disable idle observer fuzz, because only privileged content can access idle
|
||||||
|
@ -5,22 +5,37 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "mozilla/AvailableMemoryTracker.h"
|
#include "mozilla/AvailableMemoryTracker.h"
|
||||||
#include "nsThread.h"
|
|
||||||
#include "nsIObserverService.h"
|
|
||||||
#include "mozilla/Services.h"
|
|
||||||
#include "mozilla/Preferences.h"
|
|
||||||
#include "nsWindowsDllInterceptor.h"
|
|
||||||
#include "prinrval.h"
|
#include "prinrval.h"
|
||||||
#include "pratom.h"
|
#include "pratom.h"
|
||||||
#include "prenv.h"
|
#include "prenv.h"
|
||||||
|
|
||||||
#include "nsIMemoryReporter.h"
|
#include "nsIMemoryReporter.h"
|
||||||
|
#include "nsIObserver.h"
|
||||||
|
#include "nsIObserverService.h"
|
||||||
|
#include "nsIRunnable.h"
|
||||||
|
#include "nsISupports.h"
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include <windows.h>
|
#include "nsThread.h"
|
||||||
|
|
||||||
|
#include "mozilla/Preferences.h"
|
||||||
|
#include "mozilla/Services.h"
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
# include "nsWindowsDllInterceptor.h"
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MOZ_MEMORY)
|
||||||
|
# include "jemalloc.h"
|
||||||
|
#endif // MOZ_MEMORY
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
|
||||||
// We don't want our diagnostic functions to call malloc, because that could
|
// We don't want our diagnostic functions to call malloc, because that could
|
||||||
// call VirtualAlloc, and we'd end up back in here! So here are a few simple
|
// call VirtualAlloc, and we'd end up back in here! So here are a few simple
|
||||||
// debugging macros (modeled on jemalloc's), which hopefully won't allocate.
|
// debugging macros (modeled on jemalloc's), which hopefully won't allocate.
|
||||||
@ -461,6 +476,86 @@ public:
|
|||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(NumLowPhysicalMemoryEventsMemoryReporter, nsIMemoryReporter)
|
NS_IMPL_ISUPPORTS1(NumLowPhysicalMemoryEventsMemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This runnable is executed in response to a memory-pressure event; we spin
|
||||||
|
* the event-loop when receiving the memory-pressure event in the hope that
|
||||||
|
* other observers will synchronously free some memory that we'll be able to
|
||||||
|
* purge here.
|
||||||
|
*/
|
||||||
|
class nsJemallocFreeDirtyPagesRunnable MOZ_FINAL : public nsIRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIRUNNABLE
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsJemallocFreeDirtyPagesRunnable, nsIRunnable)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsJemallocFreeDirtyPagesRunnable::Run()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
#if defined(MOZ_JEMALLOC)
|
||||||
|
mallctl("arenas.purge", nullptr, 0, nullptr, 0);
|
||||||
|
#elif defined(MOZ_MEMORY)
|
||||||
|
jemalloc_free_dirty_pages();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The memory pressure watcher is used for listening to memory-pressure events
|
||||||
|
* and reacting upon them. We use one instance per process currently only for
|
||||||
|
* cleaning up dirty unused pages held by jemalloc.
|
||||||
|
*/
|
||||||
|
class nsMemoryPressureWatcher MOZ_FINAL : public nsIObserver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsMemoryPressureWatcher, nsIObserver)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize and subscribe to the memory-pressure events. We subscribe to the
|
||||||
|
* observer service in this method and not in the constructor because we need
|
||||||
|
* to hold a strong reference to 'this' before calling the observer service.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nsMemoryPressureWatcher::Init()
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||||
|
|
||||||
|
if (os) {
|
||||||
|
os->AddObserver(this, "memory-pressure", /* ownsWeak */ false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reacts to all types of memory-pressure events, launches a runnable to
|
||||||
|
* free dirty pages held by jemalloc.
|
||||||
|
* @see nsMemoryPressureWatcher::FreeDirtyPages
|
||||||
|
*/
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsMemoryPressureWatcher::Observe(nsISupports *subject, const char *topic,
|
||||||
|
const PRUnichar *data)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!strcmp(topic, "memory-pressure"), "Unknown topic");
|
||||||
|
|
||||||
|
nsRefPtr<nsIRunnable> runnable = new nsJemallocFreeDirtyPagesRunnable();
|
||||||
|
|
||||||
|
NS_DispatchToMainThread(runnable);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -468,7 +563,7 @@ namespace AvailableMemoryTracker {
|
|||||||
|
|
||||||
void Activate()
|
void Activate()
|
||||||
{
|
{
|
||||||
#if defined(_M_IX86)
|
#if defined(_M_IX86) && defined(XP_WIN)
|
||||||
MOZ_ASSERT(sInitialized);
|
MOZ_ASSERT(sInitialized);
|
||||||
MOZ_ASSERT(!sHooksActive);
|
MOZ_ASSERT(!sHooksActive);
|
||||||
|
|
||||||
@ -496,6 +591,12 @@ void Activate()
|
|||||||
}
|
}
|
||||||
sHooksActive = true;
|
sHooksActive = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (Preferences::GetBool("memory.free_dirty_pages", false)) {
|
||||||
|
// This object is held alive by the observer service.
|
||||||
|
nsRefPtr<nsMemoryPressureWatcher> watcher = new nsMemoryPressureWatcher();
|
||||||
|
watcher->Init();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
@ -509,7 +610,7 @@ void Init()
|
|||||||
// process, because we aren't going to run out of virtual memory, and the
|
// process, because we aren't going to run out of virtual memory, and the
|
||||||
// system is likely to have a fair bit of physical memory.
|
// system is likely to have a fair bit of physical memory.
|
||||||
|
|
||||||
#if defined(_M_IX86)
|
#if defined(_M_IX86) && defined(XP_WIN)
|
||||||
// Don't register the hooks if we're a build instrumented for PGO: If we're
|
// Don't register the hooks if we're a build instrumented for PGO: If we're
|
||||||
// an instrumented build, the compiler adds function calls all over the place
|
// an instrumented build, the compiler adds function calls all over the place
|
||||||
// which may call VirtualAlloc; this makes it hard to prevent
|
// which may call VirtualAlloc; this makes it hard to prevent
|
||||||
|
@ -10,10 +10,9 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace AvailableMemoryTracker {
|
namespace AvailableMemoryTracker {
|
||||||
|
|
||||||
// The AvailableMemoryTracker is implemented only on Windows. But to make
|
// The AvailableMemoryTracker launches a memory pressure watcher on all
|
||||||
// callers' lives easier, we stub out empty calls for all its public functions.
|
// platforms to react to low-memory situations and on Windows it implements
|
||||||
// So you can always initialize the AvailableMemoryTracker; it just might not
|
// the full functionality used to monitor how much memory is available.
|
||||||
// do anything.
|
|
||||||
//
|
//
|
||||||
// Init() must be called before any other threads have started, because it
|
// Init() must be called before any other threads have started, because it
|
||||||
// modifies the in-memory implementations of some DLL functions in
|
// modifies the in-memory implementations of some DLL functions in
|
||||||
@ -22,13 +21,8 @@ namespace AvailableMemoryTracker {
|
|||||||
// The hooks don't do anything until Activate() is called. It's an error to
|
// The hooks don't do anything until Activate() is called. It's an error to
|
||||||
// call Activate() without first calling Init().
|
// call Activate() without first calling Init().
|
||||||
|
|
||||||
#if defined(XP_WIN)
|
|
||||||
void Init();
|
void Init();
|
||||||
void Activate();
|
void Activate();
|
||||||
#else
|
|
||||||
void Init() {}
|
|
||||||
void Activate() {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace AvailableMemoryTracker
|
} // namespace AvailableMemoryTracker
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -43,6 +43,7 @@ CPPSRCS = \
|
|||||||
nsGZFileWriter.cpp \
|
nsGZFileWriter.cpp \
|
||||||
nsMemoryInfoDumper.cpp \
|
nsMemoryInfoDumper.cpp \
|
||||||
nsMessageLoop.cpp \
|
nsMessageLoop.cpp \
|
||||||
|
AvailableMemoryTracker.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
ifeq ($(OS_ARCH),Linux)
|
ifeq ($(OS_ARCH),Linux)
|
||||||
@ -93,8 +94,6 @@ CSRCS += pure_api.c
|
|||||||
EXPORTS += pure.h
|
EXPORTS += pure.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CPPSRCS += AvailableMemoryTracker.cpp
|
|
||||||
|
|
||||||
endif #if OS_ARCH == WINNT
|
endif #if OS_ARCH == WINNT
|
||||||
|
|
||||||
SDK_XPIDLSRCS = \
|
SDK_XPIDLSRCS = \
|
||||||
|
Loading…
Reference in New Issue
Block a user