Author: zothar
Date: 2007-01-28 16:41:37 +0000 (Sun, 28 Jan 2007)
New Revision: 11642

Added:
   trunk/freenet/src/freenet/support/OOMHandler.java
Modified:
   trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
   trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
   trunk/freenet/src/freenet/node/DNSRequester.java
   trunk/freenet/src/freenet/node/PacketSender.java
   trunk/freenet/src/freenet/node/RequestStarter.java
   trunk/freenet/src/freenet/support/FileLoggerHook.java
Log:
Factored out and updated OOM handling in some places.  Added OOM and/or 
Throwable handling in other places.  OOMs logged through the wrapper should now 
be much more informative in some cases.

Modified: trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java     
2007-01-28 14:53:53 UTC (rev 11641)
+++ trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java     
2007-01-28 16:41:37 UTC (rev 11642)
@@ -27,8 +27,9 @@
 import freenet.io.NetworkInterface;
 import freenet.node.NodeClientCore;
 import freenet.support.FileLoggerHook;
+import freenet.support.FileLoggerHook.IntervalParseException;
 import freenet.support.Logger;
-import freenet.support.FileLoggerHook.IntervalParseException;
+import freenet.support.OOMHandler;
 import freenet.support.api.BooleanCallback;
 import freenet.support.api.BucketFactory;
 import freenet.support.api.IntCallback;
@@ -397,7 +398,16 @@
                public void run() {
                        boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
                        if(logMINOR) Logger.minor(this, "Handling connection");
-                       ToadletContextImpl.handle(sock, 
SimpleToadletServer.this, bf, pageMaker);
+                       try {
+                               ToadletContextImpl.handle(sock, 
SimpleToadletServer.this, bf, pageMaker);
+                       } catch (OutOfMemoryError e) {
+                               OOMHandler.handleOOM(e);
+                               System.err.println("SimpleToadlesServer request 
above failed.");
+                       } catch (Throwable t) {
+                               System.err.println("Caught in 
SimpleToadletServer: "+t);
+                               t.printStackTrace();
+                               Logger.error(this, "Caught in 
SimpleToadletServer: "+t, t);
+                       }
                        if(logMINOR) Logger.minor(this, "Handled connection");
                }


Modified: trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/UdpSocketManager.java     2007-01-28 
14:53:53 UTC (rev 11641)
+++ trunk/freenet/src/freenet/io/comm/UdpSocketManager.java     2007-01-28 
16:41:37 UTC (rev 11642)
@@ -31,6 +31,7 @@
 import freenet.node.PeerNode;
 import freenet.support.FileLoggerHook;
 import freenet.support.Logger;
+import freenet.support.OOMHandler;
 import freenet.support.TimeUtil;

 public class UdpSocketManager extends Thread {
@@ -201,10 +202,13 @@
                        try {
                                lastTimeInSeconds = (int) 
(System.currentTimeMillis() / 1000);
                                realRun();
+            } catch (OutOfMemoryError e) {
+                               OOMHandler.handleOOM(e);
+                               System.err.println("Will retry above failed 
operation...");
                        } catch (Throwable t) {
-                               Logger.error(this, "Caught " + t, t);
                                System.err.println("Caught "+t);
                                t.printStackTrace(System.err);
+                               Logger.error(this, "Caught " + t, t);
                        }
                }
        }

Modified: trunk/freenet/src/freenet/node/DNSRequester.java
===================================================================
--- trunk/freenet/src/freenet/node/DNSRequester.java    2007-01-28 14:53:53 UTC 
(rev 11641)
+++ trunk/freenet/src/freenet/node/DNSRequester.java    2007-01-28 16:41:37 UTC 
(rev 11642)
@@ -4,6 +4,7 @@
 package freenet.node;

 import freenet.support.Logger;
+import freenet.support.OOMHandler;

 /**
  * @author amphibian
@@ -33,18 +34,8 @@
             try {
                 realRun();
             } catch (OutOfMemoryError e) {
-                Runtime r = Runtime.getRuntime();
-                long usedAtStart = r.totalMemory() - r.freeMemory();
-                System.gc();
-                System.runFinalization();
-                System.gc();
-                System.runFinalization();
-                System.err.println(e.getClass());
-                System.err.println(e.getMessage());
-                e.printStackTrace();
-                long usedNow = r.totalMemory() - r.freeMemory();
-                Logger.error(this, "Caught "+e, e);
-                Logger.error(this, "Used: "+usedAtStart+" now "+usedNow);
+                               OOMHandler.handleOOM(e);
+                               System.err.println("Will retry above failed 
operation...");
             } catch (Throwable t) {
                 Logger.error(this, "Caught in DNSRequester: "+t, t);
             }

Modified: trunk/freenet/src/freenet/node/PacketSender.java
===================================================================
--- trunk/freenet/src/freenet/node/PacketSender.java    2007-01-28 14:53:53 UTC 
(rev 11641)
+++ trunk/freenet/src/freenet/node/PacketSender.java    2007-01-28 16:41:37 UTC 
(rev 11642)
@@ -14,6 +14,7 @@
 import freenet.io.comm.NotConnectedException;
 import freenet.support.FileLoggerHook;
 import freenet.support.Logger;
+import freenet.support.OOMHandler;
 import freenet.support.WouldBlockException;

 /**
@@ -122,31 +123,8 @@
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
                 realRun();
             } catch (OutOfMemoryError e) {
-               Runtime r = null;
-               try {
-                       r = Runtime.getRuntime();
-                       long usedAtStart = r.totalMemory() - r.freeMemory();
-                       System.gc();
-                       System.runFinalization();
-                       System.gc();
-                       System.runFinalization();
-                       System.err.println(e.getClass());
-                       System.err.println(e.getMessage());
-                       e.printStackTrace();
-                       long usedNow = r.totalMemory() - r.freeMemory();
-                       Logger.error(this, "Caught "+e, e);
-                       Logger.error(this, "Used: "+usedAtStart+" now 
"+usedNow);
-               } catch (Throwable t) {
-                       // Try without GCing, it might be a thread error; GCing 
creates a thread
-                       System.err.println("Caught handling OOM "+e+" : "+t);
-                       e.printStackTrace();
-                       if(r != null)
-                               System.err.println("Memory: total 
"+r.totalMemory()+" free "+r.freeMemory()+" max "+r.maxMemory());
-                       ThreadGroup tg = 
Thread.currentThread().getThreadGroup();
-                       while(tg.getParent() != null) tg = tg.getParent();
-                       System.err.println("Running threads: 
"+tg.activeCount());
-                       WrapperManager.requestThreadDump(); // Will probably 
crash, but never mind...
-               }
+                               OOMHandler.handleOOM(e);
+                               System.err.println("Will retry above failed 
operation...");
             } catch (Throwable t) {
                 Logger.error(this, "Caught in PacketSender: "+t, t);
                 System.err.println("Caught in PacketSender: "+t);
@@ -353,9 +331,19 @@
                                        Logger.error(this, "Caught "+t+" 
running "+r, t);
                                }
                        } else {
-                               Thread t = new Thread(r, "Scheduled job: "+r);
-                               t.setDaemon(true);
-                               t.start();
+                               try {
+                                               Thread t = new Thread(r, 
"Scheduled job: "+r);
+                                               t.setDaemon(true);
+                                               t.start();
+                                       } catch (OutOfMemoryError e) {
+                                               OOMHandler.handleOOM(e);
+                                               System.err.println("Will retry 
above failed operation...");
+                                               queueTimedJob(r, 200);
+                                       } catch (Throwable t) {
+                                               Logger.error(this, "Caught in 
PacketSender: "+t, t);
+                                               System.err.println("Caught in 
PacketSender: "+t);
+                                               t.printStackTrace();
+                                       }
                        }
                }
         }

Modified: trunk/freenet/src/freenet/node/RequestStarter.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestStarter.java  2007-01-28 14:53:53 UTC 
(rev 11641)
+++ trunk/freenet/src/freenet/node/RequestStarter.java  2007-01-28 16:41:37 UTC 
(rev 11642)
@@ -4,6 +4,7 @@
 package freenet.node;

 import freenet.support.Logger;
+import freenet.support.OOMHandler;
 import freenet.support.TokenBucket;
 import freenet.support.math.RunningAverage;

@@ -93,13 +94,14 @@
                                                if(logMINOR) Logger.minor(this, 
"Started "+req+" on "+t);
                                                break;
                                        } catch (OutOfMemoryError e) {
-                                               // Probably out of threads
+                                               OOMHandler.handleOOM(e);
+                                               System.err.println("Will retry 
above failed operation...");
+                                               // Possibly out of threads
                                                try {
                                                        Thread.sleep(5000);
                                                } catch (InterruptedException 
e1) {
                                                        // Ignore
                                                }
-                                               
System.err.println(e.getMessage());
                                        }
                                }
                                sentRequestTime = System.currentTimeMillis();

Modified: trunk/freenet/src/freenet/support/FileLoggerHook.java
===================================================================
--- trunk/freenet/src/freenet/support/FileLoggerHook.java       2007-01-28 
14:53:53 UTC (rev 11641)
+++ trunk/freenet/src/freenet/support/FileLoggerHook.java       2007-01-28 
16:41:37 UTC (rev 11642)
@@ -339,6 +339,9 @@
                                if(altLogStream != null)
                                        myWrite(altLogStream, (byte[]) o);
                                } catch (OutOfMemoryError e) {
+                                       System.err.println(e.getClass());
+                                       System.err.println(e.getMessage());
+                                       e.printStackTrace();
                                    // FIXME
                                        
//freenet.node.Main.dumpInterestingObjects();
                                } catch (Throwable t) {

Added: trunk/freenet/src/freenet/support/OOMHandler.java
===================================================================
--- trunk/freenet/src/freenet/support/OOMHandler.java                           
(rev 0)
+++ trunk/freenet/src/freenet/support/OOMHandler.java   2007-01-28 16:41:37 UTC 
(rev 11642)
@@ -0,0 +1,51 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+package freenet.support;
+
+import org.tanukisoftware.wrapper.WrapperManager;
+
+import freenet.support.Logger;
+
+/**
+ * Do this processing as a standard response to an OutOfMemoryError
+ */
+public class OOMHandler {
+
+       public synchronized static void handleOOM(OutOfMemoryError e) {
+               Runtime r = null;
+               try {
+                       r = Runtime.getRuntime();
+                       long usedAtStart = r.totalMemory() - r.freeMemory();
+                       System.gc();
+                       System.runFinalization();
+                       System.gc();
+                       System.runFinalization();
+                       System.err.println(e.getClass());
+                       System.err.println(e.getMessage());
+                       e.printStackTrace();
+                       if(e.getMessage().equals("Java heap space")) {
+                               Thread.dumpStack();
+                       }
+                       long usedNow = r.totalMemory() - r.freeMemory();
+                       System.err.println("Memory: GC 
"+SizeUtil.formatSize(usedAtStart, false)+" -> "+SizeUtil.formatSize(usedNow, 
false)+": total "+SizeUtil.formatSize(r.totalMemory(), false)+" free 
"+SizeUtil.formatSize(r.freeMemory(), false)+" max 
"+SizeUtil.formatSize(r.maxMemory(), false));
+                       ThreadGroup tg = 
Thread.currentThread().getThreadGroup();
+                       while(tg.getParent() != null) tg = tg.getParent();
+                       System.err.println("Running threads: 
"+tg.activeCount());
+                       // Logger after everything else since it might throw
+                       Logger.error(null, "Caught "+e, e);
+                       Logger.error(null, "Memory: GC 
"+SizeUtil.formatSize(usedAtStart, false)+" -> "+SizeUtil.formatSize(usedNow, 
false)+": total "+SizeUtil.formatSize(r.totalMemory(), false)+" free 
"+SizeUtil.formatSize(r.freeMemory(), false)+" max 
"+SizeUtil.formatSize(r.maxMemory(), false));
+                       Logger.error(null, "Running threads: 
"+tg.activeCount());
+               } catch (Throwable t) {
+                       // Try without GCing, it might be a thread error; GCing 
creates a thread
+                       System.err.println("Caught handling OOM "+e+" : "+t);
+                       e.printStackTrace();
+                       if(r != null)
+                               System.err.println("Memory: total 
"+SizeUtil.formatSize(r.totalMemory(), false)+" free 
"+SizeUtil.formatSize(r.freeMemory(), false)+" max 
"+SizeUtil.formatSize(r.maxMemory(), false));
+                       ThreadGroup tg = 
Thread.currentThread().getThreadGroup();
+                       while(tg.getParent() != null) tg = tg.getParent();
+                       System.err.println("Running threads: 
"+tg.activeCount());
+                       WrapperManager.requestThreadDump(); // Will probably 
crash, but never mind...
+               }
+       }
+}


Reply via email to