JDK-6946825 : com.sun.net.httpserver.HttpServer; Memory Leak on Non HTTP conform open socket
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 6u10,6u19,6u20
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: linux,linux_suse_sles_10
  • CPU: x86
  • Submitted: 2010-04-23
  • Updated: 2011-10-05
  • Resolved: 2011-05-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u24-revFixed 7 b94Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux dbnu099 2.6.16.60-0.42.4-smp #1 SMP Fri Aug 14 14:33:26 UTC 2009 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
Every request on webserver port which is not http conform for example just open und direclty close a socket on webserver produce memory dust.

it looks like a memory leak.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
start a

com.sun.net.httpserver.HttpServer;

Webserver with or without context. simply start any kind of these webserver.

open a telnet connection on the webserver port and directly close it in a while loop.




EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
when i fininish these test i expected a normally running webserver.
ACTUAL -
acutally there is a memory leak. Every open socket connection on webserver produce a object that never cleaned up in memory.

This only appears when the request is non http conform request. such from a port scanner or similar.

when i make a heap dump i saw a huge amount of:

sun.nio.ch.SelektionKeyImpl
and
sun.net.httpserver.HTTPConnection

Objects, which are not cleaned up by the garbage collector. so there still is a reference.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
FEIN: RMI TCP Connection(1863)-10.1.102.144: close connection
Exception in thread "RMI TCP Connection(idle)" java.lang.OutOfMemoryError: Java heap space

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package TestServer;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;


public class HTTPServer extends Thread implements HttpHandler {
	
	private static Logger logger = Logger.getLogger("Test");
	private InetSocketAddress address;
	private HttpServer server;
	private String hostname = "localhost";
	private int port=6686;
	
	private Object waiter = new Object();
	
	private boolean isRunning=false;
	
	//private Executor exec = ThreadPoolExecutor.;
	
	
	private boolean isRunning() {
		return isRunning;
	}

	private void setRunning(boolean isRunning) {
		this.isRunning = isRunning;
	}

	public HTTPServer() {
		
        try {
        	address = new InetSocketAddress(hostname, port);
			server = HttpServer.create(address, 10);
			
	        //server.createContex
	        
	        logger.info("starting http server("+address+")");
	        
	        server.createContext("/", this);
	        //server.setExecutor(Executors.newCachedThreadPool());
	        server.start();
	        
	        this.performAction();

		} catch (Exception e) {
			e.printStackTrace();
			logger.warning(e.toString());
		}
        
	}
	
	private void performAction() {
		setRunning(true);
        Runtime.getRuntime().addShutdownHook(this);
           	
    	while (isRunning()) {
    		try {
		    	synchronized (waiter) {
		    		waiter.wait(5000);
		    	}
    		} catch (InterruptedException ie) {
    		}
    	}
    	server.stop(3);
    	//TODO unpublishAllEndpoints();
	}

	@Override
	public void handle(HttpExchange xchg) throws IOException {
		
		Headers headers = xchg.getRequestHeaders();
		logger.info("receive request from: "+xchg.getRemoteAddress());
		Set<Map.Entry<String, List<String>>> entries = headers.entrySet();

		StringBuffer response = new StringBuffer();
		for (Map.Entry<String, List<String>> entry : entries)
			response.append(entry.toString() + "\n");

		xchg.sendResponseHeaders(200, response.length());
		OutputStream os = xchg.getResponseBody();
		os.write(response.toString().getBytes());
		os.close();
	}


	public void run() {
		logger.info("HTTP Test Server ShutdownHook has been aktivated.");
		
    	setRunning(false);
    	synchronized (waiter) {
    		waiter.notifyAll();
    	}
    }

}



package TestServer;
import java.util.logging.Logger;


public class MainTest {
	
	private static Logger logger = Logger.getLogger("Test");

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		logger.info("create HTTPServer...");
		new HTTPServer();
	}

}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
dont send non http conform requests to server

Comments
EVALUATION Changeset: 0bda20126372 Author: chegar Date: 2010-05-06 17:17 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/0bda20126372 6946825: com.sun.net.httpserver.HttpServer; Memory Leak on Non HTTP conform open socket Reviewed-by: michaelm ! src/share/classes/sun/net/httpserver/ServerImpl.java
27-01-2011

EVALUATION The Server implementation keeps a list of HttpConnection instances (which hold SelektionKeyImpl instances) per connection. After accepting a new connection a HttpConnection is created and added to the list. It is never removed if the request turns out to be BAD. Other instance unnecessarily held as a result of holding the HttpConnection: sun.nio.ch.SocketChannelImpl sun.nio.ch.SelectionKeyImpl java.nio.HeapByteBuffer & [B sun.net.httpserver.Request$WriteStream sun.net.httpserver.Request$ReadStream. The solution is to remove BAD connections from the list.
27-04-2010