try {
String notifType = notification.getType();
if (!notifType.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED))
return;
MemoryPoolMXBean pool = (MemoryPoolMXBean)handback;
int numTries = 5;
for (int i=0; i<numTries; i++) {
// Memory is low! maxJvmMemory=8.323 MBytes, max for heap=7.340 MBytes, otherMem=983040, threshold reached=6.606 MBytes,
// Runtime.totalMemory=8323072, Runtime.freeMemory=1461904, usedMem=6.861 MBytes
if (log.isLoggable(Level.FINE))
log.fine(
"Memory is low! maxJvmMemory=" + Global.byteString(LowMemoryDetector.maxJvmMemory()) +
", max for heap=" + Global.byteString(pool.getUsage().getMax()) +
", otherMem=" + Global.byteString(LowMemoryDetector.maxJvmMemory() - pool.getUsage().getMax()) + // 8.323-7.340=0.983
", threshold reached=" + Global.byteString(pool.getUsageThreshold()) +
", Runtime.totalMemory=" + Global.byteString(Runtime.getRuntime().totalMemory()) +
", Runtime.freeMemory=" + Global.byteString(Runtime.getRuntime().freeMemory()) +
", usedMem=" + Global.byteString(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
System.gc();
try { Thread.sleep(1); } catch (Exception e) {}
long usedMem = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
if (usedMem < pool.getUsageThreshold()) {
if (log.isLoggable(Level.FINE))
log.fine("Low memory: Nothing to do, the garbage collector has handled it usedMem=" + Global.byteString(usedMem) + " threshold=" + Global.byteString(pool.getUsageThreshold()));
return; // Nothing to do, the garbage collector has handled it
}
}
long usedMem = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
//Memory is low! maxJvmMemory=8.323 MBytes, committed for heap=7.340 MBytes, max for heap=7.340 MBytes,
//threshold reached=6.606 MBytes, currently used=7.595 MBytes, count=2.
//Physical RAM size is 1.060 GBytes, this JVM may use max 8.323 MBytes and max 1024 file descriptors
log.severe("Memory is low! maxJvmMemory=" + Global.byteString(LowMemoryDetector.maxJvmMemory()) +
//", committed for heap=" + Global.byteString(pool.getUsage().getCommitted()) +
", max for heap=" + Global.byteString(pool.getUsage().getMax()) +
", threshold reached=" + Global.byteString(pool.getUsageThreshold()) +
", currently used=" + Global.byteString(usedMem) +
", count=" + pool.getUsageThresholdCount() +
". Physical RAM size is " + Global.byteString(Global.totalPhysicalMemorySize) + "," +
" this JVM may use max " + Global.byteString(Global.heapMemoryUsage) +
" and max " + Global.maxFileDescriptorCount + " file descriptors");
if (this.exitOnThreshold) {
System.gc();
try { Thread.sleep(1); } catch (Exception e) {}
System.gc();
try { Thread.sleep(1); } catch (Exception e) {}
usedMem = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
if (usedMem > pool.getUsageThreshold()) {
log.severe("Exiting now because of low memory (see '-xmlBlaster/jmx/exitOnMemoryThreshold true'");
System.exit(-9);
}
log.info("Garbage collected to usedMem=" + Global.byteString(usedMem) + ", we continue");
}