mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 733495 - Monitor ullAvailPageFile (available commit space) on Windows, and fire a low-memory event when it gets low. r=bsmedberg
This commit is contained in:
parent
421d17bf38
commit
8752f15ad1
@ -3461,12 +3461,16 @@ pref("dom.network.metered", false);
|
||||
// many mb of virtual address space available.
|
||||
pref("memory.low_virtual_memory_threshold_mb", 128);
|
||||
|
||||
// On Windows 32- or 64-bit, fire a low-memory notification if we have less
|
||||
// than this many mb of commit space (physical memory plus page file) left.
|
||||
pref("memory.low_commit_space_threshold_mb", 128);
|
||||
|
||||
// On Windows 32- or 64-bit, fire a low-memory notification if we have less
|
||||
// than this many mb of physical memory available on the whole machine.
|
||||
pref("memory.low_physical_memory_threshold_mb", 0);
|
||||
|
||||
// On Windows 32- or 64-bit, don't fire a low-memory notification because of
|
||||
// low available physical memory more than once every
|
||||
// low_physical_memory_notification_interval_ms.
|
||||
pref("memory.low_physical_memory_notification_interval_ms", 10000);
|
||||
// low available physical memory or low commit space more than once every
|
||||
// low_memory_notification_interval_ms.
|
||||
pref("memory.low_memory_notification_interval_ms", 10000);
|
||||
#endif
|
||||
|
@ -104,6 +104,7 @@ HISTOGRAM(MEMORY_FREE_PURGED_PAGES_MS, 1, 1024, 10, EXPONENTIAL, "Time(ms) to pu
|
||||
#elif defined(XP_WIN)
|
||||
HISTOGRAM(LOW_MEMORY_EVENTS_VIRTUAL, 1, 1024, 21, EXPONENTIAL, "Number of low-virtual-memory events fired since last ping")
|
||||
HISTOGRAM(LOW_MEMORY_EVENTS_PHYSICAL, 1, 1024, 21, EXPONENTIAL, "Number of low-physical-memory events fired since last ping")
|
||||
HISTOGRAM(LOW_MEMORY_EVENTS_COMMIT_SPACE, 1, 1024, 21, EXPONENTIAL, "Number of low-commit-space events fired since last ping")
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
@ -67,6 +67,7 @@ const MEM_HISTOGRAMS = {
|
||||
"heap-allocated": "MEMORY_HEAP_ALLOCATED",
|
||||
"page-faults-hard": "PAGE_FAULTS_HARD",
|
||||
"low-memory-events-virtual": "LOW_MEMORY_EVENTS_VIRTUAL",
|
||||
"low-memory-events-commit-space": "LOW_MEMORY_EVENTS_COMMIT_SPACE",
|
||||
"low-memory-events-physical": "LOW_MEMORY_EVENTS_PHYSICAL"
|
||||
};
|
||||
// Seconds of idle time before pinging.
|
||||
|
@ -141,10 +141,12 @@ void safe_write(PRUint64 x)
|
||||
#endif
|
||||
|
||||
PRUint32 sLowVirtualMemoryThreshold = 0;
|
||||
PRUint32 sLowCommitSpaceThreshold = 0;
|
||||
PRUint32 sLowPhysicalMemoryThreshold = 0;
|
||||
PRUint32 sLowPhysicalMemoryNotificationIntervalMS = 0;
|
||||
PRUint32 sLowMemoryNotificationIntervalMS = 0;
|
||||
|
||||
PRUint32 sNumLowVirtualMemEvents = 0;
|
||||
PRUint32 sNumLowCommitSpaceEvents = 0;
|
||||
PRUint32 sNumLowPhysicalMemEvents = 0;
|
||||
|
||||
WindowsDllInterceptor sKernel32Intercept;
|
||||
@ -173,6 +175,37 @@ HBITMAP (WINAPI *sCreateDIBSectionOrig)
|
||||
UINT aUsage, VOID **aBits,
|
||||
HANDLE aSection, DWORD aOffset);
|
||||
|
||||
/**
|
||||
* Fire a memory pressure event if it's been long enough since the last one we
|
||||
* fired.
|
||||
*/
|
||||
bool MaybeScheduleMemoryPressureEvent()
|
||||
{
|
||||
// If this interval rolls over, we may fire an extra memory pressure
|
||||
// event, but that's not a big deal.
|
||||
PRIntervalTime interval = PR_IntervalNow() - sLastLowMemoryNotificationTime;
|
||||
if (sHasScheduledOneLowMemoryNotification &&
|
||||
PR_IntervalToMilliseconds(interval) < sLowMemoryNotificationIntervalMS) {
|
||||
|
||||
LOG("Not scheduling low physical memory notification, "
|
||||
"because not enough time has elapsed since last one.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// There's a bit of a race condition here, since an interval may be a
|
||||
// 64-bit number, and 64-bit writes aren't atomic on x86-32. But let's
|
||||
// not worry about it -- the races only happen when we're already
|
||||
// experiencing memory pressure and firing notifications, so the worst
|
||||
// thing that can happen is that we fire two notifications when we
|
||||
// should have fired only one.
|
||||
sHasScheduledOneLowMemoryNotification = true;
|
||||
sLastLowMemoryNotificationTime = PR_IntervalNow();
|
||||
|
||||
LOG("Scheduling memory pressure notification.");
|
||||
ScheduleMemoryPressureEvent();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CheckMemAvailable()
|
||||
{
|
||||
MEMORYSTATUSEX stat;
|
||||
@ -185,42 +218,23 @@ void CheckMemAvailable()
|
||||
{
|
||||
// sLowVirtualMemoryThreshold is in MB, but ullAvailVirtual is in bytes.
|
||||
if (stat.ullAvailVirtual < sLowVirtualMemoryThreshold * 1024 * 1024) {
|
||||
// If we're running low on virtual memory, schedule the notification.
|
||||
// We'll probably crash if we run out of virtual memory, so don't worry
|
||||
// about firing this notification too often.
|
||||
// If we're running low on virtual memory, unconditionally schedule the
|
||||
// notification. We'll probably crash if we run out of virtual memory,
|
||||
// so don't worry about firing this notification too often.
|
||||
LOG("Detected low virtual memory.");
|
||||
PR_ATOMIC_INCREMENT(&sNumLowVirtualMemEvents);
|
||||
ScheduleMemoryPressureEvent();
|
||||
}
|
||||
else if (stat.ullAvailPageFile < sLowCommitSpaceThreshold * 1024 * 1024) {
|
||||
LOG("Detected low available page file space.");
|
||||
if (MaybeScheduleMemoryPressureEvent()) {
|
||||
PR_ATOMIC_INCREMENT(&sNumLowCommitSpaceEvents);
|
||||
}
|
||||
}
|
||||
else if (stat.ullAvailPhys < sLowPhysicalMemoryThreshold * 1024 * 1024) {
|
||||
LOG("Detected low physical memory.");
|
||||
// If the machine is running low on physical memory and it's been long
|
||||
// enough since we last fired a low-memory notification, fire a
|
||||
// notification.
|
||||
//
|
||||
// If this interval rolls over, we may fire an extra memory pressure
|
||||
// event, but that's not a big deal.
|
||||
PRIntervalTime interval = PR_IntervalNow() - sLastLowMemoryNotificationTime;
|
||||
if (!sHasScheduledOneLowMemoryNotification ||
|
||||
PR_IntervalToMilliseconds(interval) >=
|
||||
sLowPhysicalMemoryNotificationIntervalMS) {
|
||||
|
||||
// There's a bit of a race condition here, since an interval may be a
|
||||
// 64-bit number, and 64-bit writes aren't atomic on x86-32. But let's
|
||||
// not worry about it -- the races only happen when we're already
|
||||
// experiencing memory pressure and firing notifications, so the worst
|
||||
// thing that can happen is that we fire two notifications when we
|
||||
// should have fired only one.
|
||||
sHasScheduledOneLowMemoryNotification = true;
|
||||
sLastLowMemoryNotificationTime = PR_IntervalNow();
|
||||
|
||||
LOG("Scheduling memory pressure notification.");
|
||||
if (MaybeScheduleMemoryPressureEvent()) {
|
||||
PR_ATOMIC_INCREMENT(&sNumLowPhysicalMemEvents);
|
||||
ScheduleMemoryPressureEvent();
|
||||
}
|
||||
else {
|
||||
LOG("Not scheduling low physical memory notification, "
|
||||
"because not enough time has elapsed since last one.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -389,6 +403,49 @@ public:
|
||||
|
||||
NS_IMPL_ISUPPORTS1(NumLowVirtualMemoryEventsMemoryReporter, nsIMemoryReporter)
|
||||
|
||||
class NumLowCommitSpaceEventsMemoryReporter : public NumLowMemoryEventsReporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD GetPath(nsACString &aPath)
|
||||
{
|
||||
aPath.AssignLiteral("low-commit-space-events");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetAmount(PRInt64 *aAmount)
|
||||
{
|
||||
*aAmount = sNumLowCommitSpaceEvents;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetDescription(nsACString &aDescription)
|
||||
{
|
||||
aDescription.AssignLiteral(
|
||||
"Number of low-commit-space events fired since startup. ");
|
||||
|
||||
if (sLowCommitSpaceThreshold == 0 || !sHooksInstalled) {
|
||||
aDescription.Append(nsPrintfCString(1024,
|
||||
"Tracking low-commit-space events is disabled, but you can enable it "
|
||||
"by giving the memory.low_commit_space_threshold_mb pref a non-zero "
|
||||
"value%s.",
|
||||
sHooksInstalled ? "" : " and restarting"));
|
||||
}
|
||||
else {
|
||||
aDescription.Append(nsPrintfCString(1024,
|
||||
"We fire such an event if we notice there is less than %d MB of "
|
||||
"available commit space (controlled by the "
|
||||
"'memory.low_commit_space_threshold_mb' pref). Windows will likely "
|
||||
"kill us if we run out of commit space, so this event is somewhat dire.",
|
||||
sLowCommitSpaceThreshold));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(NumLowCommitSpaceEventsMemoryReporter, nsIMemoryReporter)
|
||||
|
||||
class NumLowPhysicalMemoryEventsMemoryReporter : public NumLowMemoryEventsReporter
|
||||
{
|
||||
public:
|
||||
@ -452,8 +509,10 @@ void Init()
|
||||
|
||||
Preferences::AddUintVarCache(&sLowPhysicalMemoryThreshold,
|
||||
"memory.low_physical_memory_threshold_mb", 0);
|
||||
Preferences::AddUintVarCache(&sLowPhysicalMemoryNotificationIntervalMS,
|
||||
"memory.low_physical_memory_notification_interval_ms", 10000);
|
||||
Preferences::AddUintVarCache(&sLowCommitSpaceThreshold,
|
||||
"memory.low_commit_space_threshold_mb", 128);
|
||||
Preferences::AddUintVarCache(&sLowMemoryNotificationIntervalMS,
|
||||
"memory.low_memory_notification_interval_ms", 10000);
|
||||
|
||||
// Don't register the hooks if we're a build instrumented for PGO or if both
|
||||
// thresholds are 0. (If we're an instrumented build, the compiler adds
|
||||
@ -480,6 +539,7 @@ void Init()
|
||||
sHooksInstalled = false;
|
||||
}
|
||||
|
||||
NS_RegisterMemoryReporter(new NumLowCommitSpaceEventsMemoryReporter());
|
||||
NS_RegisterMemoryReporter(new NumLowPhysicalMemoryEventsMemoryReporter());
|
||||
if (sizeof(void*) == 4) {
|
||||
NS_RegisterMemoryReporter(new NumLowVirtualMemoryEventsMemoryReporter());
|
||||
|
Loading…
Reference in New Issue
Block a user