I took a quick look at the memory situation, and there is a leak there. The
problem is that the Message class keeps a pointer to the ConnectionHandler.
Subclasses of Message are kept in the Node in messageMemories.
For every ConnectionHandler that is leaked, there are 128KB of buffer space, so
the leak is pretty fast.
I've attached a proposed fix. It works for me, but someone should review it
before I check it in. In the patch I have the ConnectionHandler null-out
its members when closed. Another approach would be to have the Message
null-out the ConnectionHandler, but I'm not sure where in the code that
should be done.
(BTW, the flags I've used are '-verbosegc' and '-Xrunhprof'. SIGQUIT causes the
latter to dump a snapshot to java.hprof.txt. Look for "SITES BEGIN" in that
file and then under the 'live objects' column.)
--
Dev Random
Fingerprint: 3ABC FCEF 1BCE 4528 E4FD 15EB 173A 76D2 6959 DAF1
Index: ConnectionHandler.java
===================================================================
RCS file: /cvsroot/freenet/Freenet/ConnectionHandler.java,v
retrieving revision 1.70
diff -u -r1.70 ConnectionHandler.java
--- ConnectionHandler.java 2000/12/05 09:57:29 1.70
+++ ConnectionHandler.java 2000/12/31 03:17:24
@@ -80,12 +80,17 @@
Core.logger.log(this,"Failed to initialize connection: " + e,
Logger.MINOR);
closed = true;
+ synchronized (c.initLock) {
+ c.initLock.notifyAll();
+ }
forceClose();
return;
} finally {
sendLock.notifyAll();
- synchronized (c.initLock) {
- c.initLock.notifyAll();
+ if (c != null) {
+ synchronized (c.initLock) {
+ c.initLock.notifyAll();
+ }
}
synchronized (initLock) {
initLock.notifyAll();
@@ -206,7 +211,7 @@
lastActiveTime = System.currentTimeMillis();
} while (!closed);
- if (c.out != null) {
+ if (c != null && c.out != null) {
Core.logger.log(this,"Finished with connection - closing",
Logger.DEBUGGING);
forceClose();
@@ -233,7 +238,7 @@
*/
public void sendMessage(Message m, MessageObject mo)
throws SendFailedException {
- while (!c.ready() && !closed) {
+ while (!closed && !c.ready()) {
synchronized(initLock) {
try {
initLock.wait();
@@ -241,7 +246,8 @@
}
}
- if (closed) throw new SendFailedException(c.getPeerAddress());
+ if (closed)
+ throw new SendFailedException((c == null) ? null : c.getPeerAddress());
synchronized(sendLock) {
unlockedSend(m, mo);
@@ -320,6 +326,9 @@
public void forceClose() {
closed = true;
c.close();
+ c = null;
+ t = null;
+ mh = null;
exec_instance.interrupt();
}
PGP signature