Author: j16sdiz
Date: 2008-04-14 13:42:39 +0000 (Mon, 14 Apr 2008)
New Revision: 19318
Added:
trunk/freenet/src/freenet/support/OOMHook.java
Modified:
trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java
trunk/freenet/src/freenet/support/OOMHandler.java
Log:
emergency pool and hook for OOMHandler
Modified: trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java
===================================================================
--- trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java 2008-04-14
13:42:11 UTC (rev 19317)
+++ trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java 2008-04-14
13:42:39 UTC (rev 19318)
@@ -38,6 +38,7 @@
import freenet.support.Fields;
import freenet.support.HexUtil;
import freenet.support.Logger;
+import freenet.support.OOMHook;
import freenet.support.SortedLongSet;
/**
@@ -48,7 +49,7 @@
* @author tubbie
* @author amphibian
*/
-public class BerkeleyDBFreenetStore implements FreenetStore {
+public class BerkeleyDBFreenetStore implements FreenetStore, OOMHook {
private static boolean logMINOR;
private static boolean logDEBUG;
@@ -2136,4 +2137,13 @@
return db;
}
+
+ public void handleOOM() throws Exception {
+ if (storeRAF != null)
+ storeRAF.getFD().sync();
+ if (keysRAF != null)
+ keysRAF.getFD().sync();
+ if (lruRAF != null)
+ lruRAF.getFD().sync();
+ }
}
Modified: trunk/freenet/src/freenet/support/OOMHandler.java
===================================================================
--- trunk/freenet/src/freenet/support/OOMHandler.java 2008-04-14 13:42:11 UTC
(rev 19317)
+++ trunk/freenet/src/freenet/support/OOMHandler.java 2008-04-14 13:42:39 UTC
(rev 19318)
@@ -3,6 +3,9 @@
* http://www.gnu.org/ for further details of the GPL. */
package freenet.support;
+import java.util.Iterator;
+import java.util.Set;
+
import org.tanukisoftware.wrapper.WrapperManager;
import freenet.support.Logger;
@@ -11,16 +14,62 @@
* Do this processing as a standard response to an OutOfMemoryError
*/
public class OOMHandler {
-
- public synchronized static void handleOOM(OutOfMemoryError e) {
+ private static volatile boolean isOOM = false;
+
+ /**
+ * Emergency memory, freed when OOM occur. Marked <code>volatile</code>
to make sure gc thread
+ * see it's free'd.
+ */
+ private static volatile byte[] emergencyPool = new byte[8192];
+
+ /**
+ * List of {@link OOMHook}s
+ */
+ private static Set oomHooks = new WeakHashSet();
+
+ public static void addOOMHook(OOMHook hook) {
+ synchronized (oomHooks) {
+ oomHooks.add(hook);
+ }
+ }
+
+ public static void handleOOM(OutOfMemoryError e) {
+ if (isOOM) {
+ Logger.error(null, "Double OOM", e);
+ return;
+ }
+
+ isOOM = true;
+
Runtime r = null;
try {
r = Runtime.getRuntime();
long usedAtStart = r.totalMemory() - r.freeMemory();
+
+ if (emergencyPool != null)
+ emergencyPool = null;
+
System.gc();
System.runFinalization();
+
+ // iterate all oom hooks
+ Iterator it = oomHooks.iterator();
+ while (it.hasNext()) {
+ OOMHook hook = ((OOMHook) it.next());
+ if (hook != null) {
+ try {
+ hook.handleOOM();
+ } catch (Throwable t) {
+ //ignore
+ }
+ }
+
+ System.gc();
+ }
+
System.gc();
System.runFinalization();
+
System.err.println(e.getClass());
System.err.println(e.getMessage());
e.printStackTrace();
@@ -46,6 +95,8 @@
while(tg.getParent() != null) tg = tg.getParent();
System.err.println("Running threads:
"+tg.activeCount());
WrapperManager.requestThreadDump(); // Will probably
crash, but never mind...
+ } finally {
+ isOOM = false;
}
}
}
Added: trunk/freenet/src/freenet/support/OOMHook.java
===================================================================
--- trunk/freenet/src/freenet/support/OOMHook.java
(rev 0)
+++ trunk/freenet/src/freenet/support/OOMHook.java 2008-04-14 13:42:39 UTC
(rev 19318)
@@ -0,0 +1,13 @@
+package freenet.support;
+
+/**
+ * @author sdiz
+ */
+public interface OOMHook {
+ /**
+ * Handle OutOfMemoryError
+ *
+ * (try to free some cache, save the files, etc).
+ */
+ void handleOOM() throws Exception;
+}