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