FULL PRODUCT VERSION :
1.6.0_20
A DESCRIPTION OF THE PROBLEM :
HttpConnection dose not removed from "Set<HttpConnection> allConnections" in class ServerImp after it closed.
All HttpConnections will be added into 'allConnections'.
&
HttpConnections will be removed:
1. private void handleEvent(Event r) {.....} in class Dispatcher
If request is a bad request, this method will not be called.
2. class ServerTimerTask extends TimerTask
This timer task only remove timeout connections in "idleConnections". But bad request connections willn't be added into "idleConnections".
Then bad request connections will never be removed from "allConnections".
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Start a simple HttpServer via JProfiler
2. Monitor objects(View Filters: sun.net.httpserver.HttpConnection)
Or
1. Add debug:
------------------------------------------------------------------------------------------------
class ServerTimerTask extends TimerTask {
public void run () {
LinkedList<HttpConnection> toClose = new LinkedList<HttpConnection>();
time = System.currentTimeMillis();
ticks ++;
synchronized (idleConnections) {
for (HttpConnection c : idleConnections) {
if (c.time <= time) {
toClose.add (c);
}
}
for (HttpConnection c : toClose) {
idleConnections.remove (c);
allConnections.remove (c);
c.close();
}
System.out.println("Idle: ["+idleConnections.size()+"] All: ["+allConnections.size()+"]");//Add debug here
}
}
}
------------------------------------------------------------------------------------------------
2. Start a simple httpserver
3. Then telnet this httpserver, you will find that the objects of HttpConnection will increase as you telnet it. And never decrease. The same as the system out.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The objects of HttpConnection should be released later.
ACTUAL -
The objects of HttpConnection not released.
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
In order to recover this bug as simple as possible, I change the class ServerTimerTask :
class ServerTimerTask extends TimerTask {
public void run() {
try{
List<HttpConnection> toRemove = new ArrayList<HttpConnection>();
time = System.currentTimeMillis();
ticks++;
synchronized (idleConnections) {
for (HttpConnection c : idleConnections) {
if (c.time <= time) {
toRemove.add(c);
c.close();
}
}
for(HttpConnection c : toRemove){
idleConnections.remove(c);
}
toRemove.clear();
}
synchronized (allConnections) {
for (HttpConnection c : allConnections) {
if(c.closed)
toRemove.add(c);
}
for(HttpConnection c : toRemove){
allConnections.remove(c);
}
toRemove.clear();
}
} catch (Throwable e){
logger.log(Level.WARNING, "[HttpServer] "+e.getMessage(), e);
}
}
}
}
SUPPORT :
YES
1.6.0_20
A DESCRIPTION OF THE PROBLEM :
HttpConnection dose not removed from "Set<HttpConnection> allConnections" in class ServerImp after it closed.
All HttpConnections will be added into 'allConnections'.
&
HttpConnections will be removed:
1. private void handleEvent(Event r) {.....} in class Dispatcher
If request is a bad request, this method will not be called.
2. class ServerTimerTask extends TimerTask
This timer task only remove timeout connections in "idleConnections". But bad request connections willn't be added into "idleConnections".
Then bad request connections will never be removed from "allConnections".
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Start a simple HttpServer via JProfiler
2. Monitor objects(View Filters: sun.net.httpserver.HttpConnection)
Or
1. Add debug:
------------------------------------------------------------------------------------------------
class ServerTimerTask extends TimerTask {
public void run () {
LinkedList<HttpConnection> toClose = new LinkedList<HttpConnection>();
time = System.currentTimeMillis();
ticks ++;
synchronized (idleConnections) {
for (HttpConnection c : idleConnections) {
if (c.time <= time) {
toClose.add (c);
}
}
for (HttpConnection c : toClose) {
idleConnections.remove (c);
allConnections.remove (c);
c.close();
}
System.out.println("Idle: ["+idleConnections.size()+"] All: ["+allConnections.size()+"]");//Add debug here
}
}
}
------------------------------------------------------------------------------------------------
2. Start a simple httpserver
3. Then telnet this httpserver, you will find that the objects of HttpConnection will increase as you telnet it. And never decrease. The same as the system out.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The objects of HttpConnection should be released later.
ACTUAL -
The objects of HttpConnection not released.
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
In order to recover this bug as simple as possible, I change the class ServerTimerTask :
class ServerTimerTask extends TimerTask {
public void run() {
try{
List<HttpConnection> toRemove = new ArrayList<HttpConnection>();
time = System.currentTimeMillis();
ticks++;
synchronized (idleConnections) {
for (HttpConnection c : idleConnections) {
if (c.time <= time) {
toRemove.add(c);
c.close();
}
}
for(HttpConnection c : toRemove){
idleConnections.remove(c);
}
toRemove.clear();
}
synchronized (allConnections) {
for (HttpConnection c : allConnections) {
if(c.closed)
toRemove.add(c);
}
for(HttpConnection c : toRemove){
allConnections.remove(c);
}
toRemove.clear();
}
} catch (Throwable e){
logger.log(Level.WARNING, "[HttpServer] "+e.getMessage(), e);
}
}
}
}
SUPPORT :
YES
- duplicates
-
JDK-6946825 com.sun.net.httpserver.HttpServer; Memory Leak on Non HTTP conform open socket
- Closed