United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6946825 : com.sun.net.httpserver.HttpServer; Memory Leak on Non HTTP conform open socket

Details
Type:
Bug
Submit Date:
2010-04-23
Status:
Closed
Updated Date:
2011-10-05
Project Name:
JDK
Resolved Date:
2011-05-18
Component:
core-libs
OS:
linux_suse_sles_10,linux
Sub-Component:
java.net
CPU:
x86
Priority:
P2
Resolution:
Fixed
Affected Versions:
6u10,6u19,6u20
Fixed Versions:

Related Reports
Backport:
Backport:
Backport:
Backport:
Duplicate:
Duplicate:
Duplicate:

Sub Tasks

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

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.
                                     
2010-04-27
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
                                     
2011-01-27



Hardware and Software, Engineered to Work Together