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;
+}


Reply via email to