Skip to Main Content

Java APIs

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Nasty memory leak using sockets inside threads

843790Feb 22 2007 — edited Feb 23 2007
In short, any time I create or use a socket inside a worker thread, that Thread object instance will never be garbage collected. The socket does not need to be connected or bound, it doesn't matter whether I close the socket or not, and it doesn't matter whether I create the Socket object inside the thread or not. As I said, it's nasty.

I initially encountered this memory leak using httpclient (which creates a worker thread for every connect() call), but it is very easy to reproduce with a small amount of stand-alone code. I'm running this test on Windows, and I encounter this memory leak using the latest 1.5 and 1.6 JDK's. I'm using the NetBeans 5.5 profiler to verify which objects are not being freed.

Here's how to reproduce it with an unbound socket created inside a worker thread:
public class Test {
	public static class TestRun extends Thread {
		public void run() {
			new Socket();
		}
	}
	
	public static void main(String[] strArgs) throws Exception {
		for(;;) {
			(new TestRun()).start();
			Thread.sleep(10);
		}
	}
}
Here's how to reproduce it with a socket created outside the thread and used inside the worker thread:
public class Test {
	public static class TestRun extends Thread {
		Socket s;
		public TestRun(Socket s) { this.s = s; }
		public void run() {
			try {
				s.bind(new InetSocketAddress(0));
				s.close();
			} catch(Exception e) {}
		}
	}
	
	public static void main(String[] strArgs) throws Exception {
		for(;;) {
			(new TestRun(new Socket())).start();
			Thread.sleep(10);
		}
	}
}
Here's how to reproduce it implementing Runnable instead of extending Thread:
public class Test {
	public static class TestRun implements Runnable {
		public void run() {
			Socket s = new Socket();
			try { s.close(); } catch(Exception e) {}
		}
	}
	
	public static void main(String[] strArgs) throws Exception {
		for(;;) {
			(new Thread(new TestRun())).start();
			Thread.sleep(10);
		}
	}
}
I've played with this a lot, and no matter what I do the Thread instance leaks if I create/use a socket inside it. The Socket instance gets cleaned up properly, as well as the TestRun instance when it's implementing Runnable, but the Thread instance never gets cleaned up. I can't see anything that would be holding a reference to it, so I can only imagine it's a problem with the JVM.

Please let me know if you can help me out with this,
Sean
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 23 2007
Added on Feb 22 2007
10 comments
1,238 views