Commit 6a9ddd12 authored by Gabriele Svelto's avatar Gabriele Svelto
Browse files

Bug 1301667 - Increase the low memory threshold under Windows and clean up the...

Bug 1301667 - Increase the low memory threshold under Windows and clean up the available memory tracker r=njn
parent 1b8ab7ef
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -4845,17 +4845,17 @@ pref("dom.netinfo.enabled", false);
#ifdef XP_WIN
// On 32-bit Windows, fire a low-memory notification if we have less than this
// many mb of virtual address space available.
pref("memory.low_virtual_memory_threshold_mb", 128);
pref("memory.low_virtual_memory_threshold_mb", 256);

// On Windows 32- or 64-bit, fire a low-memory notification if we have less
// On Windows 32-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);
pref("memory.low_commit_space_threshold_mb", 256);

// On Windows 32- or 64-bit, fire a low-memory notification if we have less
// On Windows 32-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
// On Windows 32-bit, don't fire a low-memory notification because of
// 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);
+11 −117
Original line number Diff line number Diff line
@@ -35,94 +35,8 @@ using namespace mozilla;

namespace {

#if defined(XP_WIN)

// 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
// debugging macros (modeled on jemalloc's), which hopefully won't allocate.

// #define LOGGING_ENABLED

#ifdef LOGGING_ENABLED

#define LOG(msg)       \
  do {                 \
    safe_write(msg);   \
    safe_write("\n");  \
  } while(0)

#define LOG2(m1, m2)   \
  do {                 \
    safe_write(m1);    \
    safe_write(m2);    \
    safe_write("\n");  \
  } while(0)

#define LOG3(m1, m2, m3) \
  do {                   \
    safe_write(m1);      \
    safe_write(m2);      \
    safe_write(m3);      \
    safe_write("\n");    \
  } while(0)

#define LOG4(m1, m2, m3, m4) \
  do {                       \
    safe_write(m1);          \
    safe_write(m2);          \
    safe_write(m3);          \
    safe_write(m4);          \
    safe_write("\n");        \
  } while(0)

#else

#define LOG(msg)
#define LOG2(m1, m2)
#define LOG3(m1, m2, m3)
#define LOG4(m1, m2, m3, m4)

#endif

void
safe_write(const char* aStr)
{
  // Well, puts isn't exactly "safe", but at least it doesn't call malloc...
  fputs(aStr, stdout);
}

void
safe_write(uint64_t aNum)
{
  // 2^64 is 20 decimal digits.
  const unsigned int max_len = 21;
  char buf[max_len];
  buf[max_len - 1] = '\0';

  uint32_t i;
  for (i = max_len - 2; i < max_len && aNum > 0; i--) {
    buf[i] = "0123456789"[aNum % 10];
    aNum /= 10;
  }

  safe_write(&buf[i + 1]);
}
#if defined(_M_IX86) && defined(XP_WIN)

#ifdef DEBUG
#define DEBUG_WARN_IF_FALSE(cond, msg)          \
  do {                                          \
    if (!(cond)) {                              \
      safe_write(__FILE__);                     \
      safe_write(":");                          \
      safe_write(__LINE__);                     \
      safe_write(" ");                          \
      safe_write(msg);                          \
      safe_write("\n");                         \
    }                                           \
  } while(0)
#else
#define DEBUG_WARN_IF_FALSE(cond, msg)
#endif

uint32_t sLowVirtualMemoryThreshold = 0;
uint32_t sLowCommitSpaceThreshold = 0;
@@ -173,8 +87,6 @@ MaybeScheduleMemoryPressureEvent()
  if (sHasScheduledOneLowMemoryNotification &&
      PR_IntervalToMilliseconds(interval) < sLowMemoryNotificationIntervalMS) {

    LOG("Not scheduling low physical memory notification, "
        "because not enough time has elapsed since last one.");
    return false;
  }

@@ -187,7 +99,6 @@ MaybeScheduleMemoryPressureEvent()
  sHasScheduledOneLowMemoryNotification = true;
  sLastLowMemoryNotificationTime = PR_IntervalNow();

  LOG("Scheduling memory pressure notification.");
  NS_DispatchEventualMemoryPressure(MemPressure_New);
  return true;
}
@@ -203,24 +114,19 @@ CheckMemAvailable()
  stat.dwLength = sizeof(stat);
  bool success = GlobalMemoryStatusEx(&stat);

  DEBUG_WARN_IF_FALSE(success, "GlobalMemoryStatusEx failed.");

  if (success) {
    // sLowVirtualMemoryThreshold is in MB, but ullAvailVirtual is in bytes.
    if (stat.ullAvailVirtual < sLowVirtualMemoryThreshold * 1024 * 1024) {
      // 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.");
      ++sNumLowVirtualMemEvents;
      NS_DispatchEventualMemoryPressure(MemPressure_New);
    } else if (stat.ullAvailPageFile < sLowCommitSpaceThreshold * 1024 * 1024) {
      LOG("Detected low available page file space.");
      if (MaybeScheduleMemoryPressureEvent()) {
        ++sNumLowCommitSpaceEvents;
      }
    } else if (stat.ullAvailPhys < sLowPhysicalMemoryThreshold * 1024 * 1024) {
      LOG("Detected low physical memory.");
      if (MaybeScheduleMemoryPressureEvent()) {
        ++sNumLowPhysicalMemEvents;
      }
@@ -252,7 +158,6 @@ VirtualAllocHook(LPVOID aAddress, SIZE_T aSize,
  // we're not tracking low physical memory.
  if ((sLowVirtualMemoryThreshold != 0 && aAllocationType & MEM_RESERVE) ||
      (sLowPhysicalMemoryThreshold != 0 && aAllocationType & MEM_COMMIT)) {
    LOG3("VirtualAllocHook(size=", aSize, ")");
    CheckMemAvailable();
  }

@@ -269,7 +174,6 @@ MapViewOfFileHook(HANDLE aFileMappingObject,
  LPVOID result = sMapViewOfFileOrig(aFileMappingObject, aDesiredAccess,
                                     aFileOffsetHigh, aFileOffsetLow,
                                     aNumBytesToMap);
  LOG("MapViewOfFileHook");
  CheckMemAvailable();
  return result;
}
@@ -309,7 +213,6 @@ CreateDIBSectionHook(HDC aDC,
    // If we're allocating more than 1MB, check how much memory is left after
    // the allocation.
    if (size > 1024 * 1024 * 8) {
      LOG3("CreateDIBSectionHook: Large allocation (size=", size, ")");
      doCheck = true;
    }
  }
@@ -346,8 +249,6 @@ public:
  NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
                            nsISupports* aData, bool aAnonymize) override
  {
    // We only do virtual-memory tracking on 32-bit builds.
    if (sizeof(void*) == 4) {
    MOZ_COLLECT_REPORT(
      "low-memory-events/virtual", KIND_OTHER, UNITS_COUNT_CUMULATIVE,
      LowMemoryEventsVirtualDistinguishedAmount(),
@@ -356,10 +257,9 @@ public:
"virtual address space available (if zero, this behavior is disabled). The "
"process will probably crash if it runs out of virtual address space, so "
"this event is dire.");
    }

    MOZ_COLLECT_REPORT(
      "low-commit-space-events", KIND_OTHER, UNITS_COUNT_CUMULATIVE,
      "low-memory-events/commit-space", KIND_OTHER, UNITS_COUNT_CUMULATIVE,
      sNumLowCommitSpaceEvents,
"Number of low-commit-space events fired since startup. We fire such an "
"event if we notice there is less than memory.low_commit_space_threshold_mb of "
@@ -381,7 +281,7 @@ public:
};
NS_IMPL_ISUPPORTS(LowEventsReporter, nsIMemoryReporter)

#endif // defined(XP_WIN)
#endif // defined(_M_IX86) && defined(XP_WIN)

/**
 * This runnable is executed in response to a memory-pressure event; we spin
@@ -484,21 +384,15 @@ Activate()
  MOZ_ASSERT(sInitialized);
  MOZ_ASSERT(!sHooksActive);

  // On 64-bit systems, hardcode sLowVirtualMemoryThreshold to 0 -- we assume
  // we're not going to run out of virtual memory!
  if (sizeof(void*) > 4) {
    sLowVirtualMemoryThreshold = 0;
  } else {
  Preferences::AddUintVarCache(&sLowVirtualMemoryThreshold,
                                 "memory.low_virtual_mem_threshold_mb", 128);
  }

                               "memory.low_virtual_mem_threshold_mb", 256);
  Preferences::AddUintVarCache(&sLowPhysicalMemoryThreshold,
                               "memory.low_physical_memory_threshold_mb", 0);
  Preferences::AddUintVarCache(&sLowCommitSpaceThreshold,
                               "memory.low_commit_space_threshold_mb", 128);
                               "memory.low_commit_space_threshold_mb", 256);
  Preferences::AddUintVarCache(&sLowMemoryNotificationIntervalMS,
                               "memory.low_memory_notification_interval_ms", 10000);
                               "memory.low_memory_notification_interval_ms",
                               10000);

  RegisterStrongMemoryReporter(new LowEventsReporter());
  RegisterLowMemoryEventsVirtualDistinguishedAmount(