users@grizzly.java.net

Re: Closing connections

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Thu, 03 Jul 2008 11:56:10 -0400

Salut,

Mark Hig wrote:
> Hi,
> I have had a quick try of your suggestion. I am not sure that this is the
> answer. The JVM runs out of memory quite quickly at quite low loads.
>
> I am running an asynchronous Grizzly server, as mentioned above. I have
> tried a simple ping style test through Grizzly that just provides a simple
> response. I have tested this set up with JMeter and it performs well on my
> laptop, running in Eclipse upto about 150 users.
>
> However, replacing the response with your suggested disconnect technique in
> the AsyncAdapter:
>
> Just call the following method and the connection will be resumed/closed:
>
> // Finish the response
> processorTask.postResponse();
>
> // Clean up the objects
> processorTask.postProcess();
>
> Internally, Grizzly will make sure the connection is closed and the
> associated recycled (for re-use).
>
> (Obviously after doing the above, I can not do the Async callback to clean
> up because the processorTask no longer exists.)
>
> Grizzly runs out of memory within 2 minutes at only a 50 user load:

Hum that's strange. Can you share your code so I can take a look? I
suspect ProcessorTask aren't recycled properly. As an example, just take
a look at how I do that for Grizzly Comet:

https://grizzly.dev.java.net/nonav/xref/com/sun/grizzly/comet/CometAsyncFilter.html
https://grizzly.dev.java.net/nonav/xref/com/sun/grizzly/comet/CometEngine.html

When resuming the connection, I've just manipulate the
AsynchProcessorTask(apt) by first making sure the request/response
object are properly recycled:

532 apt.setStage(AsyncTask.POST_EXECUTE);
533 try{
534 apt.doTask();
535 } catch (IllegalStateException ex){
536 if (logger.isLoggable(Level.FINEST)){
537 logger.log(Level.FINEST,"flushResponse failed",ex);
538 }
539 } catch (IOException ex) {
540 logger.log(Level.SEVERE,"flushResponse failed",ex);
541 }

then resume

AsyncHandler.removeFromInterruptedQueue(apt);

The exception below really means ProcessorTask aren't recycled and you
end up with too many of them.

>
> SEVERE: Java heap space
> java.lang.OutOfMemoryError: Java heap space
> at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:39)
> at java.nio.ByteBuffer.allocate(ByteBuffer.java:312)
> at
> com.sun.grizzly.http.SocketChannelOutputBuffer.<init>(SocketChannelOutputBuffer.java:105)
> at
> com.sun.grizzly.http.DefaultProcessorTask.initialize(DefaultProcessorTask.java:425)
> at
> com.sun.grizzly.http.DefaultProcessorTask.preProcess(DefaultProcessorTask.java:477)
> at
> com.sun.grizzly.http.DefaultProcessorTask.preProcess(DefaultProcessorTask.java:463)
> at
> com.sun.grizzly.arp.DefaultAsyncExecutor.preExecute(DefaultAsyncExecutor.java:138)
> at
> com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:90)
> at com.sun.grizzly.http.TaskBase.call(TaskBase.java:359)
> at com.sun.grizzly.util.WorkerThreadImpl.run(WorkerThreadImpl.java:169)
> 03-Jul-2008 15:55:17 com.sun.grizzly.http.DefaultProcessorTask postResponse
> SEVERE: processorTask.errorFinishingResponse
> java.lang.NullPointerException
> at
> com.sun.grizzly.http.DefaultProcessorTask.postResponse(DefaultProcessorTask.java:585)
> at
> com.sun.grizzly.arp.DefaultAsyncExecutor.postExecute(DefaultAsyncExecutor.java:191)
> at
> com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:101)
> at com.sun.grizzly.http.TaskBase.call(TaskBase.java:359)
> at com.sun.grizzly.util.WorkerThreadImpl.run(WorkerThreadImpl.java:169)
> 03-Jul-2008 15:55:17 com.sun.grizzly.arp.AsyncProcessorTask doTask
> SEVERE: null
> java.lang.NullPointerException
> at
> com.sun.grizzly.http.DefaultProcessorTask.postResponse(DefaultProcessorTask.java:608)
> at
> com.sun.grizzly.arp.DefaultAsyncExecutor.postExecute(DefaultAsyncExecutor.java:191)
> at
> com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:101)
> at com.sun.grizzly.http.TaskBase.call(TaskBase.java:359)
> at com.sun.grizzly.util.WorkerThreadImpl.run(WorkerThreadImpl.java:169)
> 03-Jul-2008 15:55:17 com.sun.grizzly.util.WorkerThreadImpl run
> SEVERE: WorkerThreadImpl unexpected exception:
> java.lang.RuntimeException: java.lang.NullPointerException
> at
> com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:112)
> at com.sun.grizzly.http.TaskBase.call(TaskBase.java:359)
> at com.sun.grizzly.util.WorkerThreadImpl.run(WorkerThreadImpl.java:169)
> Caused by: java.lang.NullPointerException
> at
> com.sun.grizzly.http.DefaultProcessorTask.postResponse(DefaultProcessorTask.java:608)
> at
> com.sun.grizzly.arp.DefaultAsyncExecutor.postExecute(DefaultAsyncExecutor.java:191)
> at
> com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:101)
> ... 2 more
>
> This suggests that Grizzly is not clearing its resources when I am trying to
> close the connection.

Exactly.


>
>
> Trying Oleksiy's suggestion of just cancelling the key:
>
> Grizzly, by default, doesn't have any resource associated with the
> connection - so it should be safe enough to close connection using
> method:
> SelectionKeyHandler.cancel(SelectionKey)
>
>
> Grizzly throws the following errors for each cancelled connection:
>
>

Can you add the exception?

> This is what I would expect. However, Grizzly seems to be far more stable
> taking this approach. There were no memory errors running on a 50 user load
> as above.

Yes, internally Grizzly is recovering (this is what I suspect). Can you
share your code? If not, send it to me privately and I will take a look.

>
>
> Do you have any mnore suggestions as to what is the correct approach for
> cancelling a connection?

I need more info but Alexey's recommendation might be a good solution
for this situation, but I do think using the Grizzly APR is a more clean
solution.

Thanks

-- Jeanfrancois


>
> Thanks
>
> --- Mark
>
>
>
> Jeanfrancois Arcand-2 wrote:
>> Salut,
>>
>> Oleksiy Stashok wrote:
>>> Ok.
>>> Grizzly, by default, doesn't have any resource associated with the
>>> connection - so it should be safe enough to close connection using
>>> method:
>>> SelectionKeyHandler.cancel(SelectionKey)
>> I would not touch that as the HTTP object will not be recycled and http
>> response/connection will be in limbo.
>>
>>> For sure if you're inside some HTTP processor, there could be some HTTP
>>> specific way of closing the connection. Jean-Francois can advice better
>>> here.
>> Done :-)
>>
>> -- Jeanfrancois
>>
>>
>>> Thanks.
>>>
>>> WBR,
>>> Alexey.
>>>
>>> On Jun 20, 2008, at 15:54 , Mark Hig wrote:
>>>
>>>> Yes we are. We are using Grizzly 1.8 http and framework.
>>>> --
>>>> View this message in context:
>>>> http://www.nabble.com/Closing-connections-tp18026485p18030095.html
>>>> Sent from the Grizzly - Users mailing list archive at Nabble.com.
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>
>>
>>
>