memory usage with asyncfilter

View: New views
6 Messages — Rating Filter:   Alert me  

memory usage with asyncfilter

by rama.rama@tiscali.it :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ok back :D

let's be back to memory usage issue.



at the end fo the
mail you can found the test that i have used to found this issue.

let
me explain how and why i think that there is something of strange.


1)
i'll start a gws, with a static adapter that say "yo"
2) this gws,
after a 2500ms, will do a GC :)
3) after a small warmup, a couple of
secs, this is the memory usage
RE 0 MU 1788240
this means that i
haven't do any request and that 1788240 is the minimal memory usage of
this example.


now, let's start  AB benchmark.

ab -c 200 -n 20000
http://192.168.2.143:8080/

wait a bit (to have some GC issued) and
copy again the memory usage
RE 20001 MU 6038432 --> after the AB (why
there s 1 more request?? maybe my code is stupid)
RE 20001 MU 4419504 --
> 1 min later :)



let's start the 1st test with a AsyncFilter.
The
asyncfilter, added to this gws, is configured as follow. If the uri
contains "rama" it will just schedule the request to be issued 10 ms
later.
if not, the request will simply proceed.

Let's start it! and
allow a little warmup :)
RE 0 MU 1786376
pretty much the same of
before, so we are ready for the test!


now, let's start  AB benchmark.


ab -c 200 -n 20000 http://192.168.2.143:8080/ --> as you can notice,
there isn't any "rama" on the uri, so asyncfilter, will just pass the
request to be executed later :)

and we got
RE 20076 MU 62715680 -->
after the AB (why there is 76 more request?? maybe ab is stupid?!? :))

RE 20076 MU 56168440 --> 3 mins later (sorry i have a call hehehe)


In
any case, you can see the enormous memory usage while using asyncfilter
(and without even suspending a request!!)


So, just with the 1st test,
i am a bit worried about that..maybe my fault? if so, please, check the
example and let me know where is the error (i have copy the example
here http://weblogs.java.
net/blog/jfarcand/archive/2008/07/extending_the_g.html btw)


let's
start the 2nd test case.
Same code of above.

ab -c 200 -n 20000 http:
//192.168.2.143:8080/rama (so suspend is on)

and we got
RE 20005 MU
68343376 --> after AB (05?? what the hell!!)
RE 20005 MU 68293528 --> 1
mins later

Any help is appreciated :)

and here is the test code!


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

package test;

import com.eg.euler.ipc.http.newHttp.EulerAsyncAdapter;

import com.sun.grizzly.arp.AsyncExecutor;
import com.sun.grizzly.arp.
AsyncFilter;
import com.sun.grizzly.http.embed.GrizzlyWebServer;
import
com.sun.grizzly.tcp.http11.GrizzlyAdapter;
import com.sun.grizzly.tcp.
http11.GrizzlyRequest;
import com.sun.grizzly.tcp.http11.
GrizzlyResponse;

import java.io.IOException;
import java.util.
concurrent.Callable;
import java.util.concurrent.
ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by
IntelliJ IDEA.
 * User: Rama
 * Date: 30-ott-2009
 * Time: 11.49.46
 */

public class DemoWebServer  {

    static final AtomicInteger req = new
AtomicInteger();
    public static void main(String args[]){
         
GrizzlyWebServer test = new GrizzlyWebServer();
          test.
addGrizzlyAdapter(new MyGrizzlyAdapter(),new String[]{"/"});
         
test.addAsyncFilter(new MyAsyncFilter());
          test.
getSelectorThread().setDisplayConfiguration(true);
          try {

            test.start();
          } catch (IOException e){

            e.printStackTrace();  //To change body of catch statement
use File | Settings | File Templates.
          }
          while
(true) {

              int reqn = req.get();
              System.out.
println("RE "+reqn+" MU "+(Runtime.getRuntime().totalMemory() -Runtime.
getRuntime().freeMemory()));
              try {
                Thread.
sleep(2500);
                System.gc();System.gc();System.gc();

              } catch (Exception e) {

              }
             

          }
    }


    static class MyGrizzlyAdapter extends
GrizzlyAdapter {
        public void service(GrizzlyRequest
grizzlyRequest, GrizzlyResponse grizzlyResponse) {
            try {

                grizzlyResponse.getWriter().print("Great!");

                req.incrementAndGet();
            } catch (IOException
e) {

            }
        }
    }

    static class MyAsyncFilter
implements AsyncFilter {
        private final
ScheduledThreadPoolExecutor scheduler =
                               
new ScheduledThreadPoolExecutor(1);

        public boolean doFilter
(final AsyncExecutor asyncExecutor) {
            String url =
asyncExecutor.getProcessorTask().getRequestURI();


            //if
req url is rama, then delay the request
            if (url.contains
("rama")) {
                scheduler.schedule(new Callable() {

                        public Object call() throws Exception {

                            asyncExecutor.execute();

                            asyncExecutor.postExecute();

                            return null;
                        }

                }, 10, TimeUnit.MILLISECONDS);
                return
false;
            }

            //if not, let them pass :)

            try {
             asyncExecutor.execute();
             
asyncExecutor.postExecute();
            } catch (Exception e) {


            }

            return false;
        }
    }

}




------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------








Passa a Tiscali Tutto Incluso Light: telefono + adsl 8 Mb senza limiti a soli 9,95 euro al mese fino al 01/04/2010. Gratis la Sim Tiscali Mobile con 25 euro di traffico.  L’offerta è valida solo se attivi entro il 29/10/09   http://abbonati.tiscali.it/telefono-adsl/prodotti/tc/tuttoincluso_light/?WT.mc_id=01fw

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@...
For additional commands, e-mail: dev-help@...


Re: memory usage with asyncfilter

by Oleksiy Stashok :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Rama,

IMO I've found what causes the higher memory consumption, when  
AsyncFilter is enabled.

Here are my findings, which will help to understand the issue and fix  
I'm proposing...

Basically there is no leak, but because of specific, how we run  
AsyncProcessorTask - we create and cache much more ProcessorTasks  
objects, than for regular usecause without AsyncFilters.
By specific, I mean approach how we're running AsyncProcessorTask in  
DefaultAsyncHandler.handle() method. Each AsyncProcessorTask is run in  
a *new* worker thread (which seems redundant for me, because the  
current thread is a worker thread). The situation is following...  
Assume we have thread pool with max 5 threads and 50 HTTP requests  
come simultaneously. We enqueue those requests tasks in a worker  
thread queue.

1) Thread-Pool queue:
50 Request tasks

Now first thread picks up first request task, which polls  
ProcessorTask cache, which is empty, so it creates new ProcessorTask  
and executes it using AsyncProcessorTask in a new worker thread. So  
basically we processed so called request task, but added new  
AsyncProcessorTask on a worker thread queue.

2) Thread-Pool queue:
49 Request tasks
1 AsyncProcessorTask

The same situation happens with the 2nd request task, again we create  
new ProcessorTask and execute it using AsyncProcessorTask in a new  
worker thread. So basically enqueue one more AsyncProcessorTask.

3) Thread-Pool queue:
48 Request tasks
2 AsyncProcessorTask

So finally we will come to up to *50* ProcessorTasks created to  
process 50 requests, which then will be stored in ProcessorTask cache.

Notice, that in normal usecase, without AsyncFilters, we will have  
only *5* ProcessorTasks in cache, one per each thread.

So the easiest solution I can propose is to run AsyncProcessorTasks in  
the current worker thread (diff is attached).

Jeanfrancois, can I ask you to review it?

Thanks.

WBR,
Alexey.






On Oct 30, 2009, at 12:30 , rama.rama@... wrote:

> Ok back :D
>
> let's be back to memory usage issue.
>
>
>
> at the end fo the
> mail you can found the test that i have used to found this issue.
>
> let
> me explain how and why i think that there is something of strange.
>
>
> 1)
> i'll start a gws, with a static adapter that say "yo"
> 2) this gws,
> after a 2500ms, will do a GC :)
> 3) after a small warmup, a couple of
> secs, this is the memory usage
> RE 0 MU 1788240
> this means that i
> haven't do any request and that 1788240 is the minimal memory usage of
> this example.
>
>
> now, let's start  AB benchmark.
>
> ab -c 200 -n 20000
> http://192.168.2.143:8080/
>
> wait a bit (to have some GC issued) and
> copy again the memory usage
> RE 20001 MU 6038432 --> after the AB (why
> there s 1 more request?? maybe my code is stupid)
> RE 20001 MU 4419504 --
>> 1 min later :)
>
>
>
> let's start the 1st test with a AsyncFilter.
> The
> asyncfilter, added to this gws, is configured as follow. If the uri
> contains "rama" it will just schedule the request to be issued 10 ms
> later.
> if not, the request will simply proceed.
>
> Let's start it! and
> allow a little warmup :)
> RE 0 MU 1786376
> pretty much the same of
> before, so we are ready for the test!
>
>
> now, let's start  AB benchmark.
>
>
> ab -c 200 -n 20000 http://192.168.2.143:8080/ --> as you can notice,
> there isn't any "rama" on the uri, so asyncfilter, will just pass the
> request to be executed later :)
>
> and we got
> RE 20076 MU 62715680 -->
> after the AB (why there is 76 more request?? maybe ab is stupid?!? :))
>
> RE 20076 MU 56168440 --> 3 mins later (sorry i have a call hehehe)
>
>
> In
> any case, you can see the enormous memory usage while using  
> asyncfilter
> (and without even suspending a request!!)
>
>
> So, just with the 1st test,
> i am a bit worried about that..maybe my fault? if so, please, check  
> the
> example and let me know where is the error (i have copy the example
> here http://weblogs.java.
> net/blog/jfarcand/archive/2008/07/extending_the_g.html btw)
>
>
> let's
> start the 2nd test case.
> Same code of above.
>
> ab -c 200 -n 20000 http:
> //192.168.2.143:8080/rama (so suspend is on)
>
> and we got
> RE 20005 MU
> 68343376 --> after AB (05?? what the hell!!)
> RE 20005 MU 68293528 --> 1
> mins later
>
> Any help is appreciated :)
>
> and here is the test code!
>
>
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> package test;
>
> import com.eg.euler.ipc.http.newHttp.EulerAsyncAdapter;
>
> import com.sun.grizzly.arp.AsyncExecutor;
> import com.sun.grizzly.arp.
> AsyncFilter;
> import com.sun.grizzly.http.embed.GrizzlyWebServer;
> import
> com.sun.grizzly.tcp.http11.GrizzlyAdapter;
> import com.sun.grizzly.tcp.
> http11.GrizzlyRequest;
> import com.sun.grizzly.tcp.http11.
> GrizzlyResponse;
>
> import java.io.IOException;
> import java.util.
> concurrent.Callable;
> import java.util.concurrent.
> ScheduledThreadPoolExecutor;
> import java.util.concurrent.TimeUnit;
>
> import java.util.concurrent.atomic.AtomicInteger;
>
> /**
> * Created by
> IntelliJ IDEA.
> * User: Rama
> * Date: 30-ott-2009
> * Time: 11.49.46
> */
>
> public class DemoWebServer  {
>
>    static final AtomicInteger req = new
> AtomicInteger();
>    public static void main(String args[]){
>
> GrizzlyWebServer test = new GrizzlyWebServer();
>          test.
> addGrizzlyAdapter(new MyGrizzlyAdapter(),new String[]{"/"});
>
> test.addAsyncFilter(new MyAsyncFilter());
>          test.
> getSelectorThread().setDisplayConfiguration(true);
>          try {
>
>            test.start();
>          } catch (IOException e){
>
>            e.printStackTrace();  //To change body of catch statement
> use File | Settings | File Templates.
>          }
>          while
> (true) {
>
>              int reqn = req.get();
>              System.out.
> println("RE "+reqn+" MU "+(Runtime.getRuntime().totalMemory() -
> Runtime.
> getRuntime().freeMemory()));
>              try {
>                Thread.
> sleep(2500);
>                System.gc();System.gc();System.gc();
>
>              } catch (Exception e) {
>
>              }
>
>
>          }
>    }
>
>
>    static class MyGrizzlyAdapter extends
> GrizzlyAdapter {
>        public void service(GrizzlyRequest
> grizzlyRequest, GrizzlyResponse grizzlyResponse) {
>            try {
>
>                grizzlyResponse.getWriter().print("Great!");
>
>                req.incrementAndGet();
>            } catch (IOException
> e) {
>
>            }
>        }
>    }
>
>    static class MyAsyncFilter
> implements AsyncFilter {
>        private final
> ScheduledThreadPoolExecutor scheduler =
>
> new ScheduledThreadPoolExecutor(1);
>
>        public boolean doFilter
> (final AsyncExecutor asyncExecutor) {
>            String url =
> asyncExecutor.getProcessorTask().getRequestURI();
>
>
>            //if
> req url is rama, then delay the request
>            if (url.contains
> ("rama")) {
>                scheduler.schedule(new Callable() {
>
>                        public Object call() throws Exception {
>
>                            asyncExecutor.execute();
>
>                            asyncExecutor.postExecute();
>
>                            return null;
>                        }
>
>                }, 10, TimeUnit.MILLISECONDS);
>                return
> false;
>            }
>
>            //if not, let them pass :)
>
>            try {
>             asyncExecutor.execute();
>
> asyncExecutor.postExecute();
>            } catch (Exception e) {
>
>
>            }
>
>            return false;
>        }
>    }
>
> }
>
>
>
>
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>
>
>
>
>
>
>
> Passa a Tiscali Tutto Incluso Light: telefono + adsl 8 Mb senza  
> limiti a soli 9,95 euro al mese fino al 01/04/2010. Gratis la Sim  
> Tiscali Mobile con 25 euro di traffico.  L’offerta è valida solo se  
> attivi entro il 29/10/09   http://abbonati.tiscali.it/telefono-adsl/prodotti/tc/tuttoincluso_light/?WT.mc_id=01fw
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@...
> For additional commands, e-mail: dev-help@...
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@...
For additional commands, e-mail: dev-help@...

DefaultAsyncHandler.diff (1K) Download Attachment

Re: memory usage with asyncfilter

by Jeanfrancois Arcand-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Salut,

Oleksiy Stashok wrote:

> Hi Rama,
>
> IMO I've found what causes the higher memory consumption, when
> AsyncFilter is enabled.
>
> Here are my findings, which will help to understand the issue and fix
> I'm proposing...
>
> Basically there is no leak, but because of specific, how we run
> AsyncProcessorTask - we create and cache much more ProcessorTasks
> objects, than for regular usecause without AsyncFilters.
> By specific, I mean approach how we're running AsyncProcessorTask in
> DefaultAsyncHandler.handle() method. Each AsyncProcessorTask is run in a
> *new* worker thread (which seems redundant for me, because the current
> thread is a worker thread).

No, it will not work with Comet if we remove that second thread. I will
give a try to your patch as I did ARP in 2005, and we may be able to
remove the second thread pool


  The situation is following... Assume we have

> thread pool with max 5 threads and 50 HTTP requests come simultaneously.
> We enqueue those requests tasks in a worker thread queue.
>
> 1) Thread-Pool queue:
> 50 Request tasks
>
> Now first thread picks up first request task, which polls ProcessorTask
> cache, which is empty, so it creates new ProcessorTask and executes it
> using AsyncProcessorTask in a new worker thread. So basically we
> processed so called request task, but added new AsyncProcessorTask on a
> worker thread queue.
>
> 2) Thread-Pool queue:
> 49 Request tasks
> 1 AsyncProcessorTask
>
> The same situation happens with the 2nd request task, again we create
> new ProcessorTask and execute it using AsyncProcessorTask in a new
> worker thread. So basically enqueue one more AsyncProcessorTask.
>
> 3) Thread-Pool queue:
> 48 Request tasks
> 2 AsyncProcessorTask
>
> So finally we will come to up to *50* ProcessorTasks created to process
> 50 requests, which then will be stored in ProcessorTask cache.

Yes, since ProcessorTask references the request bytes buffer, we ust
have one ProcessorTask per suspended request. Note that alternative,
Grizzly Async API, does the same as well. We can't get rid of the
ProcessorTask, unfortunalty.


>
> Notice, that in normal usecase, without AsyncFilters, we will have only
> *5* ProcessorTasks in cache, one per each thread.
>
> So the easiest solution I can propose is to run AsyncProcessorTasks in
> the current worker thread (diff is attached).
>
> Jeanfrancois, can I ask you to review it?

I suspect Comet will not works with the patch.

A+

-- Jeanfrancois


>
> Thanks.
>
> WBR,
> Alexey.
>
>
>
>
> On Oct 30, 2009, at 12:30 , rama.rama@... wrote:
>
>> Ok back :D
>>
>> let's be back to memory usage issue.
>>
>>
>>
>> at the end fo the
>> mail you can found the test that i have used to found this issue.
>>
>> let
>> me explain how and why i think that there is something of strange.
>>
>>
>> 1)
>> i'll start a gws, with a static adapter that say "yo"
>> 2) this gws,
>> after a 2500ms, will do a GC :)
>> 3) after a small warmup, a couple of
>> secs, this is the memory usage
>> RE 0 MU 1788240
>> this means that i
>> haven't do any request and that 1788240 is the minimal memory usage of
>> this example.
>>
>>
>> now, let's start  AB benchmark.
>>
>> ab -c 200 -n 20000
>> http://192.168.2.143:8080/
>>
>> wait a bit (to have some GC issued) and
>> copy again the memory usage
>> RE 20001 MU 6038432 --> after the AB (why
>> there s 1 more request?? maybe my code is stupid)
>> RE 20001 MU 4419504 --
>>> 1 min later :)
>>
>>
>>
>> let's start the 1st test with a AsyncFilter.
>> The
>> asyncfilter, added to this gws, is configured as follow. If the uri
>> contains "rama" it will just schedule the request to be issued 10 ms
>> later.
>> if not, the request will simply proceed.
>>
>> Let's start it! and
>> allow a little warmup :)
>> RE 0 MU 1786376
>> pretty much the same of
>> before, so we are ready for the test!
>>
>>
>> now, let's start  AB benchmark.
>>
>>
>> ab -c 200 -n 20000 http://192.168.2.143:8080/ --> as you can notice,
>> there isn't any "rama" on the uri, so asyncfilter, will just pass the
>> request to be executed later :)
>>
>> and we got
>> RE 20076 MU 62715680 -->
>> after the AB (why there is 76 more request?? maybe ab is stupid?!? :))
>>
>> RE 20076 MU 56168440 --> 3 mins later (sorry i have a call hehehe)
>>
>>
>> In
>> any case, you can see the enormous memory usage while using asyncfilter
>> (and without even suspending a request!!)
>>
>>
>> So, just with the 1st test,
>> i am a bit worried about that..maybe my fault? if so, please, check the
>> example and let me know where is the error (i have copy the example
>> here http://weblogs.java.
>> net/blog/jfarcand/archive/2008/07/extending_the_g.html btw)
>>
>>
>> let's
>> start the 2nd test case.
>> Same code of above.
>>
>> ab -c 200 -n 20000 http:
>> //192.168.2.143:8080/rama (so suspend is on)
>>
>> and we got
>> RE 20005 MU
>> 68343376 --> after AB (05?? what the hell!!)
>> RE 20005 MU 68293528 --> 1
>> mins later
>>
>> Any help is appreciated :)
>>
>> and here is the test code!
>>
>>
>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>>
>>
>> package test;
>>
>> import com.eg.euler.ipc.http.newHttp.EulerAsyncAdapter;
>>
>> import com.sun.grizzly.arp.AsyncExecutor;
>> import com.sun.grizzly.arp.
>> AsyncFilter;
>> import com.sun.grizzly.http.embed.GrizzlyWebServer;
>> import
>> com.sun.grizzly.tcp.http11.GrizzlyAdapter;
>> import com.sun.grizzly.tcp.
>> http11.GrizzlyRequest;
>> import com.sun.grizzly.tcp.http11.
>> GrizzlyResponse;
>>
>> import java.io.IOException;
>> import java.util.
>> concurrent.Callable;
>> import java.util.concurrent.
>> ScheduledThreadPoolExecutor;
>> import java.util.concurrent.TimeUnit;
>>
>> import java.util.concurrent.atomic.AtomicInteger;
>>
>> /**
>> * Created by
>> IntelliJ IDEA.
>> * User: Rama
>> * Date: 30-ott-2009
>> * Time: 11.49.46
>> */
>>
>> public class DemoWebServer  {
>>
>>    static final AtomicInteger req = new
>> AtomicInteger();
>>    public static void main(String args[]){
>>
>> GrizzlyWebServer test = new GrizzlyWebServer();
>>          test.
>> addGrizzlyAdapter(new MyGrizzlyAdapter(),new String[]{"/"});
>>
>> test.addAsyncFilter(new MyAsyncFilter());
>>          test.
>> getSelectorThread().setDisplayConfiguration(true);
>>          try {
>>
>>            test.start();
>>          } catch (IOException e){
>>
>>            e.printStackTrace();  //To change body of catch statement
>> use File | Settings | File Templates.
>>          }
>>          while
>> (true) {
>>
>>              int reqn = req.get();
>>              System.out.
>> println("RE "+reqn+" MU "+(Runtime.getRuntime().totalMemory() -Runtime.
>> getRuntime().freeMemory()));
>>              try {
>>                Thread.
>> sleep(2500);
>>                System.gc();System.gc();System.gc();
>>
>>              } catch (Exception e) {
>>
>>              }
>>
>>
>>          }
>>    }
>>
>>
>>    static class MyGrizzlyAdapter extends
>> GrizzlyAdapter {
>>        public void service(GrizzlyRequest
>> grizzlyRequest, GrizzlyResponse grizzlyResponse) {
>>            try {
>>
>>                grizzlyResponse.getWriter().print("Great!");
>>
>>                req.incrementAndGet();
>>            } catch (IOException
>> e) {
>>
>>            }
>>        }
>>    }
>>
>>    static class MyAsyncFilter
>> implements AsyncFilter {
>>        private final
>> ScheduledThreadPoolExecutor scheduler =
>>
>> new ScheduledThreadPoolExecutor(1);
>>
>>        public boolean doFilter
>> (final AsyncExecutor asyncExecutor) {
>>            String url =
>> asyncExecutor.getProcessorTask().getRequestURI();
>>
>>
>>            //if
>> req url is rama, then delay the request
>>            if (url.contains
>> ("rama")) {
>>                scheduler.schedule(new Callable() {
>>
>>                        public Object call() throws Exception {
>>
>>                            asyncExecutor.execute();
>>
>>                            asyncExecutor.postExecute();
>>
>>                            return null;
>>                        }
>>
>>                }, 10, TimeUnit.MILLISECONDS);
>>                return
>> false;
>>            }
>>
>>            //if not, let them pass :)
>>
>>            try {
>>             asyncExecutor.execute();
>>
>> asyncExecutor.postExecute();
>>            } catch (Exception e) {
>>
>>
>>            }
>>
>>            return false;
>>        }
>>    }
>>
>> }
>>
>>
>>
>>
>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> Passa a Tiscali Tutto Incluso Light: telefono + adsl 8 Mb senza limiti
>> a soli 9,95 euro al mese fino al 01/04/2010. Gratis la Sim Tiscali
>> Mobile con 25 euro di traffico.  L’offerta è valida solo se attivi
>> entro il 29/10/09  
>> http://abbonati.tiscali.it/telefono-adsl/prodotti/tc/tuttoincluso_light/?WT.mc_id=01fw 
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@...
>> For additional commands, e-mail: dev-help@...
>>
>
>
>
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@...
> For additional commands, e-mail: dev-help@...

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@...
For additional commands, e-mail: dev-help@...


Re: memory usage with asyncfilter

by Oleksiy Stashok :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

Jeanfrancois, once you'll have time, can you pls. take a look at this?

Thanks.

WBR,
Alexey.

On Nov 3, 2009, at 16:00 , Jeanfrancois Arcand wrote:

> Salut,
>
> Oleksiy Stashok wrote:
>> Hi Rama,
>> IMO I've found what causes the higher memory consumption, when  
>> AsyncFilter is enabled.
>> Here are my findings, which will help to understand the issue and  
>> fix I'm proposing...
>> Basically there is no leak, but because of specific, how we run  
>> AsyncProcessorTask - we create and cache much more ProcessorTasks  
>> objects, than for regular usecause without AsyncFilters.
>> By specific, I mean approach how we're running AsyncProcessorTask  
>> in DefaultAsyncHandler.handle() method. Each AsyncProcessorTask is  
>> run in a *new* worker thread (which seems redundant for me, because  
>> the current thread is a worker thread).
>
> No, it will not work with Comet if we remove that second thread. I  
> will give a try to your patch as I did ARP in 2005, and we may be  
> able to remove the second thread pool
>
>
> The situation is following... Assume we have
>> thread pool with max 5 threads and 50 HTTP requests come  
>> simultaneously. We enqueue those requests tasks in a worker thread  
>> queue.
>> 1) Thread-Pool queue:
>> 50 Request tasks
>> Now first thread picks up first request task, which polls  
>> ProcessorTask cache, which is empty, so it creates new  
>> ProcessorTask and executes it using AsyncProcessorTask in a new  
>> worker thread. So basically we processed so called request task,  
>> but added new AsyncProcessorTask on a worker thread queue.
>> 2) Thread-Pool queue:
>> 49 Request tasks
>> 1 AsyncProcessorTask
>> The same situation happens with the 2nd request task, again we  
>> create new ProcessorTask and execute it using AsyncProcessorTask in  
>> a new worker thread. So basically enqueue one more  
>> AsyncProcessorTask.
>> 3) Thread-Pool queue:
>> 48 Request tasks
>> 2 AsyncProcessorTask
>> So finally we will come to up to *50* ProcessorTasks created to  
>> process 50 requests, which then will be stored in ProcessorTask  
>> cache.
>
> Yes, since ProcessorTask references the request bytes buffer, we ust  
> have one ProcessorTask per suspended request. Note that alternative,  
> Grizzly Async API, does the same as well. We can't get rid of the  
> ProcessorTask, unfortunalty.
>
>
>> Notice, that in normal usecase, without AsyncFilters, we will have  
>> only *5* ProcessorTasks in cache, one per each thread.
>> So the easiest solution I can propose is to run AsyncProcessorTasks  
>> in the current worker thread (diff is attached).
>> Jeanfrancois, can I ask you to review it?
>
> I suspect Comet will not works with the patch.
>
> A+
>
> -- Jeanfrancois
>
>
>> Thanks.
>> WBR,
>> Alexey.
>> On Oct 30, 2009, at 12:30 , rama.rama@... wrote:
>>> Ok back :D
>>>
>>> let's be back to memory usage issue.
>>>
>>>
>>>
>>> at the end fo the
>>> mail you can found the test that i have used to found this issue.
>>>
>>> let
>>> me explain how and why i think that there is something of strange.
>>>
>>>
>>> 1)
>>> i'll start a gws, with a static adapter that say "yo"
>>> 2) this gws,
>>> after a 2500ms, will do a GC :)
>>> 3) after a small warmup, a couple of
>>> secs, this is the memory usage
>>> RE 0 MU 1788240
>>> this means that i
>>> haven't do any request and that 1788240 is the minimal memory  
>>> usage of
>>> this example.
>>>
>>>
>>> now, let's start  AB benchmark.
>>>
>>> ab -c 200 -n 20000
>>> http://192.168.2.143:8080/
>>>
>>> wait a bit (to have some GC issued) and
>>> copy again the memory usage
>>> RE 20001 MU 6038432 --> after the AB (why
>>> there s 1 more request?? maybe my code is stupid)
>>> RE 20001 MU 4419504 --
>>>> 1 min later :)
>>>
>>>
>>>
>>> let's start the 1st test with a AsyncFilter.
>>> The
>>> asyncfilter, added to this gws, is configured as follow. If the uri
>>> contains "rama" it will just schedule the request to be issued 10 ms
>>> later.
>>> if not, the request will simply proceed.
>>>
>>> Let's start it! and
>>> allow a little warmup :)
>>> RE 0 MU 1786376
>>> pretty much the same of
>>> before, so we are ready for the test!
>>>
>>>
>>> now, let's start  AB benchmark.
>>>
>>>
>>> ab -c 200 -n 20000 http://192.168.2.143:8080/ --> as you can notice,
>>> there isn't any "rama" on the uri, so asyncfilter, will just pass  
>>> the
>>> request to be executed later :)
>>>
>>> and we got
>>> RE 20076 MU 62715680 -->
>>> after the AB (why there is 76 more request?? maybe ab is  
>>> stupid?!? :))
>>>
>>> RE 20076 MU 56168440 --> 3 mins later (sorry i have a call hehehe)
>>>
>>>
>>> In
>>> any case, you can see the enormous memory usage while using  
>>> asyncfilter
>>> (and without even suspending a request!!)
>>>
>>>
>>> So, just with the 1st test,
>>> i am a bit worried about that..maybe my fault? if so, please,  
>>> check the
>>> example and let me know where is the error (i have copy the example
>>> here http://weblogs.java.
>>> net/blog/jfarcand/archive/2008/07/extending_the_g.html btw)
>>>
>>>
>>> let's
>>> start the 2nd test case.
>>> Same code of above.
>>>
>>> ab -c 200 -n 20000 http:
>>> //192.168.2.143:8080/rama (so suspend is on)
>>>
>>> and we got
>>> RE 20005 MU
>>> 68343376 --> after AB (05?? what the hell!!)
>>> RE 20005 MU 68293528 --> 1
>>> mins later
>>>
>>> Any help is appreciated :)
>>>
>>> and here is the test code!
>>>
>>>
>>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
>>> package test;
>>>
>>> import com.eg.euler.ipc.http.newHttp.EulerAsyncAdapter;
>>>
>>> import com.sun.grizzly.arp.AsyncExecutor;
>>> import com.sun.grizzly.arp.
>>> AsyncFilter;
>>> import com.sun.grizzly.http.embed.GrizzlyWebServer;
>>> import
>>> com.sun.grizzly.tcp.http11.GrizzlyAdapter;
>>> import com.sun.grizzly.tcp.
>>> http11.GrizzlyRequest;
>>> import com.sun.grizzly.tcp.http11.
>>> GrizzlyResponse;
>>>
>>> import java.io.IOException;
>>> import java.util.
>>> concurrent.Callable;
>>> import java.util.concurrent.
>>> ScheduledThreadPoolExecutor;
>>> import java.util.concurrent.TimeUnit;
>>>
>>> import java.util.concurrent.atomic.AtomicInteger;
>>>
>>> /**
>>> * Created by
>>> IntelliJ IDEA.
>>> * User: Rama
>>> * Date: 30-ott-2009
>>> * Time: 11.49.46
>>> */
>>>
>>> public class DemoWebServer  {
>>>
>>>   static final AtomicInteger req = new
>>> AtomicInteger();
>>>   public static void main(String args[]){
>>>
>>> GrizzlyWebServer test = new GrizzlyWebServer();
>>>         test.
>>> addGrizzlyAdapter(new MyGrizzlyAdapter(),new String[]{"/"});
>>>
>>> test.addAsyncFilter(new MyAsyncFilter());
>>>         test.
>>> getSelectorThread().setDisplayConfiguration(true);
>>>         try {
>>>
>>>           test.start();
>>>         } catch (IOException e){
>>>
>>>           e.printStackTrace();  //To change body of catch statement
>>> use File | Settings | File Templates.
>>>         }
>>>         while
>>> (true) {
>>>
>>>             int reqn = req.get();
>>>             System.out.
>>> println("RE "+reqn+" MU "+(Runtime.getRuntime().totalMemory() -
>>> Runtime.
>>> getRuntime().freeMemory()));
>>>             try {
>>>               Thread.
>>> sleep(2500);
>>>               System.gc();System.gc();System.gc();
>>>
>>>             } catch (Exception e) {
>>>
>>>             }
>>>
>>>
>>>         }
>>>   }
>>>
>>>
>>>   static class MyGrizzlyAdapter extends
>>> GrizzlyAdapter {
>>>       public void service(GrizzlyRequest
>>> grizzlyRequest, GrizzlyResponse grizzlyResponse) {
>>>           try {
>>>
>>>               grizzlyResponse.getWriter().print("Great!");
>>>
>>>               req.incrementAndGet();
>>>           } catch (IOException
>>> e) {
>>>
>>>           }
>>>       }
>>>   }
>>>
>>>   static class MyAsyncFilter
>>> implements AsyncFilter {
>>>       private final
>>> ScheduledThreadPoolExecutor scheduler =
>>>
>>> new ScheduledThreadPoolExecutor(1);
>>>
>>>       public boolean doFilter
>>> (final AsyncExecutor asyncExecutor) {
>>>           String url =
>>> asyncExecutor.getProcessorTask().getRequestURI();
>>>
>>>
>>>           //if
>>> req url is rama, then delay the request
>>>           if (url.contains
>>> ("rama")) {
>>>               scheduler.schedule(new Callable() {
>>>
>>>                       public Object call() throws Exception {
>>>
>>>                           asyncExecutor.execute();
>>>
>>>                           asyncExecutor.postExecute();
>>>
>>>                           return null;
>>>                       }
>>>
>>>               }, 10, TimeUnit.MILLISECONDS);
>>>               return
>>> false;
>>>           }
>>>
>>>           //if not, let them pass :)
>>>
>>>           try {
>>>            asyncExecutor.execute();
>>>
>>> asyncExecutor.postExecute();
>>>           } catch (Exception e) {
>>>
>>>
>>>           }
>>>
>>>           return false;
>>>       }
>>>   }
>>>
>>> }
>>>
>>>
>>>
>>>
>>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> Passa a Tiscali Tutto Incluso Light: telefono + adsl 8 Mb senza  
>>> limiti a soli 9,95 euro al mese fino al 01/04/2010. Gratis la Sim  
>>> Tiscali Mobile con 25 euro di traffico.  L’offerta è valida solo  
>>> se attivi entro il 29/10/09   http://abbonati.tiscali.it/telefono-adsl/prodotti/tc/tuttoincluso_light/?WT.mc_id=01fw
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@...
>>> For additional commands, e-mail: dev-help@...
>>>
>> ------------------------------------------------------------------------
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@...
>> For additional commands, e-mail: dev-help@...
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@...
> For additional commands, e-mail: dev-help@...
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@...
For additional commands, e-mail: dev-help@...


Re: memory usage with asyncfilter

by Jeanfrancois Arcand-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Salut,

Oleksiy Stashok wrote:
> Hi,
>
> Jeanfrancois, once you'll have time, can you pls. take a look at this?

sure I will. Did you try to run a Comet demo with your patch? I think if
we Comet still working we should go ahead but as far as I can tell, the
extra thread pool was required to fully support async operation.

A+

-- Jeanfrancois


>
> Thanks.
>
> WBR,
> Alexey.
>
> On Nov 3, 2009, at 16:00 , Jeanfrancois Arcand wrote:
>
>> Salut,
>>
>> Oleksiy Stashok wrote:
>>> Hi Rama,
>>> IMO I've found what causes the higher memory consumption, when
>>> AsyncFilter is enabled.
>>> Here are my findings, which will help to understand the issue and fix
>>> I'm proposing...
>>> Basically there is no leak, but because of specific, how we run
>>> AsyncProcessorTask - we create and cache much more ProcessorTasks
>>> objects, than for regular usecause without AsyncFilters.
>>> By specific, I mean approach how we're running AsyncProcessorTask in
>>> DefaultAsyncHandler.handle() method. Each AsyncProcessorTask is run
>>> in a *new* worker thread (which seems redundant for me, because the
>>> current thread is a worker thread).
>>
>> No, it will not work with Comet if we remove that second thread. I
>> will give a try to your patch as I did ARP in 2005, and we may be able
>> to remove the second thread pool
>>
>>
>> The situation is following... Assume we have
>>> thread pool with max 5 threads and 50 HTTP requests come
>>> simultaneously. We enqueue those requests tasks in a worker thread
>>> queue.
>>> 1) Thread-Pool queue:
>>> 50 Request tasks
>>> Now first thread picks up first request task, which polls
>>> ProcessorTask cache, which is empty, so it creates new ProcessorTask
>>> and executes it using AsyncProcessorTask in a new worker thread. So
>>> basically we processed so called request task, but added new
>>> AsyncProcessorTask on a worker thread queue.
>>> 2) Thread-Pool queue:
>>> 49 Request tasks
>>> 1 AsyncProcessorTask
>>> The same situation happens with the 2nd request task, again we create
>>> new ProcessorTask and execute it using AsyncProcessorTask in a new
>>> worker thread. So basically enqueue one more AsyncProcessorTask.
>>> 3) Thread-Pool queue:
>>> 48 Request tasks
>>> 2 AsyncProcessorTask
>>> So finally we will come to up to *50* ProcessorTasks created to
>>> process 50 requests, which then will be stored in ProcessorTask cache.
>>
>> Yes, since ProcessorTask references the request bytes buffer, we ust
>> have one ProcessorTask per suspended request. Note that alternative,
>> Grizzly Async API, does the same as well. We can't get rid of the
>> ProcessorTask, unfortunalty.
>>
>>
>>> Notice, that in normal usecase, without AsyncFilters, we will have
>>> only *5* ProcessorTasks in cache, one per each thread.
>>> So the easiest solution I can propose is to run AsyncProcessorTasks
>>> in the current worker thread (diff is attached).
>>> Jeanfrancois, can I ask you to review it?
>>
>> I suspect Comet will not works with the patch.
>>
>> A+
>>
>> -- Jeanfrancois
>>
>>
>>> Thanks.
>>> WBR,
>>> Alexey.
>>> On Oct 30, 2009, at 12:30 , rama.rama@... wrote:
>>>> Ok back :D
>>>>
>>>> let's be back to memory usage issue.
>>>>
>>>>
>>>>
>>>> at the end fo the
>>>> mail you can found the test that i have used to found this issue.
>>>>
>>>> let
>>>> me explain how and why i think that there is something of strange.
>>>>
>>>>
>>>> 1)
>>>> i'll start a gws, with a static adapter that say "yo"
>>>> 2) this gws,
>>>> after a 2500ms, will do a GC :)
>>>> 3) after a small warmup, a couple of
>>>> secs, this is the memory usage
>>>> RE 0 MU 1788240
>>>> this means that i
>>>> haven't do any request and that 1788240 is the minimal memory usage of
>>>> this example.
>>>>
>>>>
>>>> now, let's start  AB benchmark.
>>>>
>>>> ab -c 200 -n 20000
>>>> http://192.168.2.143:8080/
>>>>
>>>> wait a bit (to have some GC issued) and
>>>> copy again the memory usage
>>>> RE 20001 MU 6038432 --> after the AB (why
>>>> there s 1 more request?? maybe my code is stupid)
>>>> RE 20001 MU 4419504 --
>>>>> 1 min later :)
>>>>
>>>>
>>>>
>>>> let's start the 1st test with a AsyncFilter.
>>>> The
>>>> asyncfilter, added to this gws, is configured as follow. If the uri
>>>> contains "rama" it will just schedule the request to be issued 10 ms
>>>> later.
>>>> if not, the request will simply proceed.
>>>>
>>>> Let's start it! and
>>>> allow a little warmup :)
>>>> RE 0 MU 1786376
>>>> pretty much the same of
>>>> before, so we are ready for the test!
>>>>
>>>>
>>>> now, let's start  AB benchmark.
>>>>
>>>>
>>>> ab -c 200 -n 20000 http://192.168.2.143:8080/ --> as you can notice,
>>>> there isn't any "rama" on the uri, so asyncfilter, will just pass the
>>>> request to be executed later :)
>>>>
>>>> and we got
>>>> RE 20076 MU 62715680 -->
>>>> after the AB (why there is 76 more request?? maybe ab is stupid?!? :))
>>>>
>>>> RE 20076 MU 56168440 --> 3 mins later (sorry i have a call hehehe)
>>>>
>>>>
>>>> In
>>>> any case, you can see the enormous memory usage while using asyncfilter
>>>> (and without even suspending a request!!)
>>>>
>>>>
>>>> So, just with the 1st test,
>>>> i am a bit worried about that..maybe my fault? if so, please, check the
>>>> example and let me know where is the error (i have copy the example
>>>> here http://weblogs.java.
>>>> net/blog/jfarcand/archive/2008/07/extending_the_g.html btw)
>>>>
>>>>
>>>> let's
>>>> start the 2nd test case.
>>>> Same code of above.
>>>>
>>>> ab -c 200 -n 20000 http:
>>>> //192.168.2.143:8080/rama (so suspend is on)
>>>>
>>>> and we got
>>>> RE 20005 MU
>>>> 68343376 --> after AB (05?? what the hell!!)
>>>> RE 20005 MU 68293528 --> 1
>>>> mins later
>>>>
>>>> Any help is appreciated :)
>>>>
>>>> and here is the test code!
>>>>
>>>>
>>>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>>>>
>>>>
>>>> package test;
>>>>
>>>> import com.eg.euler.ipc.http.newHttp.EulerAsyncAdapter;
>>>>
>>>> import com.sun.grizzly.arp.AsyncExecutor;
>>>> import com.sun.grizzly.arp.
>>>> AsyncFilter;
>>>> import com.sun.grizzly.http.embed.GrizzlyWebServer;
>>>> import
>>>> com.sun.grizzly.tcp.http11.GrizzlyAdapter;
>>>> import com.sun.grizzly.tcp.
>>>> http11.GrizzlyRequest;
>>>> import com.sun.grizzly.tcp.http11.
>>>> GrizzlyResponse;
>>>>
>>>> import java.io.IOException;
>>>> import java.util.
>>>> concurrent.Callable;
>>>> import java.util.concurrent.
>>>> ScheduledThreadPoolExecutor;
>>>> import java.util.concurrent.TimeUnit;
>>>>
>>>> import java.util.concurrent.atomic.AtomicInteger;
>>>>
>>>> /**
>>>> * Created by
>>>> IntelliJ IDEA.
>>>> * User: Rama
>>>> * Date: 30-ott-2009
>>>> * Time: 11.49.46
>>>> */
>>>>
>>>> public class DemoWebServer  {
>>>>
>>>>   static final AtomicInteger req = new
>>>> AtomicInteger();
>>>>   public static void main(String args[]){
>>>>
>>>> GrizzlyWebServer test = new GrizzlyWebServer();
>>>>         test.
>>>> addGrizzlyAdapter(new MyGrizzlyAdapter(),new String[]{"/"});
>>>>
>>>> test.addAsyncFilter(new MyAsyncFilter());
>>>>         test.
>>>> getSelectorThread().setDisplayConfiguration(true);
>>>>         try {
>>>>
>>>>           test.start();
>>>>         } catch (IOException e){
>>>>
>>>>           e.printStackTrace();  //To change body of catch statement
>>>> use File | Settings | File Templates.
>>>>         }
>>>>         while
>>>> (true) {
>>>>
>>>>             int reqn = req.get();
>>>>             System.out.
>>>> println("RE "+reqn+" MU "+(Runtime.getRuntime().totalMemory() -Runtime.
>>>> getRuntime().freeMemory()));
>>>>             try {
>>>>               Thread.
>>>> sleep(2500);
>>>>               System.gc();System.gc();System.gc();
>>>>
>>>>             } catch (Exception e) {
>>>>
>>>>             }
>>>>
>>>>
>>>>         }
>>>>   }
>>>>
>>>>
>>>>   static class MyGrizzlyAdapter extends
>>>> GrizzlyAdapter {
>>>>       public void service(GrizzlyRequest
>>>> grizzlyRequest, GrizzlyResponse grizzlyResponse) {
>>>>           try {
>>>>
>>>>               grizzlyResponse.getWriter().print("Great!");
>>>>
>>>>               req.incrementAndGet();
>>>>           } catch (IOException
>>>> e) {
>>>>
>>>>           }
>>>>       }
>>>>   }
>>>>
>>>>   static class MyAsyncFilter
>>>> implements AsyncFilter {
>>>>       private final
>>>> ScheduledThreadPoolExecutor scheduler =
>>>>
>>>> new ScheduledThreadPoolExecutor(1);
>>>>
>>>>       public boolean doFilter
>>>> (final AsyncExecutor asyncExecutor) {
>>>>           String url =
>>>> asyncExecutor.getProcessorTask().getRequestURI();
>>>>
>>>>
>>>>           //if
>>>> req url is rama, then delay the request
>>>>           if (url.contains
>>>> ("rama")) {
>>>>               scheduler.schedule(new Callable() {
>>>>
>>>>                       public Object call() throws Exception {
>>>>
>>>>                           asyncExecutor.execute();
>>>>
>>>>                           asyncExecutor.postExecute();
>>>>
>>>>                           return null;
>>>>                       }
>>>>
>>>>               }, 10, TimeUnit.MILLISECONDS);
>>>>               return
>>>> false;
>>>>           }
>>>>
>>>>           //if not, let them pass :)
>>>>
>>>>           try {
>>>>            asyncExecutor.execute();
>>>>
>>>> asyncExecutor.postExecute();
>>>>           } catch (Exception e) {
>>>>
>>>>
>>>>           }
>>>>
>>>>           return false;
>>>>       }
>>>>   }
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Passa a Tiscali Tutto Incluso Light: telefono + adsl 8 Mb senza
>>>> limiti a soli 9,95 euro al mese fino al 01/04/2010. Gratis la Sim
>>>> Tiscali Mobile con 25 euro di traffico.  L’offerta è valida solo se
>>>> attivi entro il 29/10/09  
>>>> http://abbonati.tiscali.it/telefono-adsl/prodotti/tc/tuttoincluso_light/?WT.mc_id=01fw 
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe@...
>>>> For additional commands, e-mail: dev-help@...
>>>>
>>> ------------------------------------------------------------------------
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@...
>>> For additional commands, e-mail: dev-help@...
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@...
>> For additional commands, e-mail: dev-help@...
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@...
> For additional commands, e-mail: dev-help@...
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@...
For additional commands, e-mail: dev-help@...


Re: memory usage with asyncfilter

by Jeanfrancois Arcand-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Salut,

Oleksiy Stashok wrote:
> Hi,
>
> Jeanfrancois, once you'll have time, can you pls. take a look at this?

sure I will. Did you try to run a Comet demo with your patch? I think if
we Comet still working we should go ahead but as far as I can tell, the
extra thread pool was required to fully support async operation.

A+

-- Jeanfrancois


>
> Thanks.
>
> WBR,
> Alexey.
>
> On Nov 3, 2009, at 16:00 , Jeanfrancois Arcand wrote:
>
>> Salut,
>>
>> Oleksiy Stashok wrote:
>>> Hi Rama,
>>> IMO I've found what causes the higher memory consumption, when
>>> AsyncFilter is enabled.
>>> Here are my findings, which will help to understand the issue and fix
>>> I'm proposing...
>>> Basically there is no leak, but because of specific, how we run
>>> AsyncProcessorTask - we create and cache much more ProcessorTasks
>>> objects, than for regular usecause without AsyncFilters.
>>> By specific, I mean approach how we're running AsyncProcessorTask in
>>> DefaultAsyncHandler.handle() method. Each AsyncProcessorTask is run
>>> in a *new* worker thread (which seems redundant for me, because the
>>> current thread is a worker thread).
>>
>> No, it will not work with Comet if we remove that second thread. I
>> will give a try to your patch as I did ARP in 2005, and we may be able
>> to remove the second thread pool
>>
>>
>> The situation is following... Assume we have
>>> thread pool with max 5 threads and 50 HTTP requests come
>>> simultaneously. We enqueue those requests tasks in a worker thread
>>> queue.
>>> 1) Thread-Pool queue:
>>> 50 Request tasks
>>> Now first thread picks up first request task, which polls
>>> ProcessorTask cache, which is empty, so it creates new ProcessorTask
>>> and executes it using AsyncProcessorTask in a new worker thread. So
>>> basically we processed so called request task, but added new
>>> AsyncProcessorTask on a worker thread queue.
>>> 2) Thread-Pool queue:
>>> 49 Request tasks
>>> 1 AsyncProcessorTask
>>> The same situation happens with the 2nd request task, again we create
>>> new ProcessorTask and execute it using AsyncProcessorTask in a new
>>> worker thread. So basically enqueue one more AsyncProcessorTask.
>>> 3) Thread-Pool queue:
>>> 48 Request tasks
>>> 2 AsyncProcessorTask
>>> So finally we will come to up to *50* ProcessorTasks created to
>>> process 50 requests, which then will be stored in ProcessorTask cache.
>>
>> Yes, since ProcessorTask references the request bytes buffer, we ust
>> have one ProcessorTask per suspended request. Note that alternative,
>> Grizzly Async API, does the same as well. We can't get rid of the
>> ProcessorTask, unfortunalty.
>>
>>
>>> Notice, that in normal usecase, without AsyncFilters, we will have
>>> only *5* ProcessorTasks in cache, one per each thread.
>>> So the easiest solution I can propose is to run AsyncProcessorTasks
>>> in the current worker thread (diff is attached).
>>> Jeanfrancois, can I ask you to review it?
>>
>> I suspect Comet will not works with the patch.
>>
>> A+
>>
>> -- Jeanfrancois
>>
>>
>>> Thanks.
>>> WBR,
>>> Alexey.
>>> On Oct 30, 2009, at 12:30 , rama.rama@... wrote:
>>>> Ok back :D
>>>>
>>>> let's be back to memory usage issue.
>>>>
>>>>
>>>>
>>>> at the end fo the
>>>> mail you can found the test that i have used to found this issue.
>>>>
>>>> let
>>>> me explain how and why i think that there is something of strange.
>>>>
>>>>
>>>> 1)
>>>> i'll start a gws, with a static adapter that say "yo"
>>>> 2) this gws,
>>>> after a 2500ms, will do a GC :)
>>>> 3) after a small warmup, a couple of
>>>> secs, this is the memory usage
>>>> RE 0 MU 1788240
>>>> this means that i
>>>> haven't do any request and that 1788240 is the minimal memory usage of
>>>> this example.
>>>>
>>>>
>>>> now, let's start  AB benchmark.
>>>>
>>>> ab -c 200 -n 20000
>>>> http://192.168.2.143:8080/
>>>>
>>>> wait a bit (to have some GC issued) and
>>>> copy again the memory usage
>>>> RE 20001 MU 6038432 --> after the AB (why
>>>> there s 1 more request?? maybe my code is stupid)
>>>> RE 20001 MU 4419504 --
>>>>> 1 min later :)
>>>>
>>>>
>>>>
>>>> let's start the 1st test with a AsyncFilter.
>>>> The
>>>> asyncfilter, added to this gws, is configured as follow. If the uri
>>>> contains "rama" it will just schedule the request to be issued 10 ms
>>>> later.
>>>> if not, the request will simply proceed.
>>>>
>>>> Let's start it! and
>>>> allow a little warmup :)
>>>> RE 0 MU 1786376
>>>> pretty much the same of
>>>> before, so we are ready for the test!
>>>>
>>>>
>>>> now, let's start  AB benchmark.
>>>>
>>>>
>>>> ab -c 200 -n 20000 http://192.168.2.143:8080/ --> as you can notice,
>>>> there isn't any "rama" on the uri, so asyncfilter, will just pass the
>>>> request to be executed later :)
>>>>
>>>> and we got
>>>> RE 20076 MU 62715680 -->
>>>> after the AB (why there is 76 more request?? maybe ab is stupid?!? :))
>>>>
>>>> RE 20076 MU 56168440 --> 3 mins later (sorry i have a call hehehe)
>>>>
>>>>
>>>> In
>>>> any case, you can see the enormous memory usage while using asyncfilter
>>>> (and without even suspending a request!!)
>>>>
>>>>
>>>> So, just with the 1st test,
>>>> i am a bit worried about that..maybe my fault? if so, please, check the
>>>> example and let me know where is the error (i have copy the example
>>>> here http://weblogs.java.
>>>> net/blog/jfarcand/archive/2008/07/extending_the_g.html btw)
>>>>
>>>>
>>>> let's
>>>> start the 2nd test case.
>>>> Same code of above.
>>>>
>>>> ab -c 200 -n 20000 http:
>>>> //192.168.2.143:8080/rama (so suspend is on)
>>>>
>>>> and we got
>>>> RE 20005 MU
>>>> 68343376 --> after AB (05?? what the hell!!)
>>>> RE 20005 MU 68293528 --> 1
>>>> mins later
>>>>
>>>> Any help is appreciated :)
>>>>
>>>> and here is the test code!
>>>>
>>>>
>>>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>>>>
>>>>
>>>> package test;
>>>>
>>>> import com.eg.euler.ipc.http.newHttp.EulerAsyncAdapter;
>>>>
>>>> import com.sun.grizzly.arp.AsyncExecutor;
>>>> import com.sun.grizzly.arp.
>>>> AsyncFilter;
>>>> import com.sun.grizzly.http.embed.GrizzlyWebServer;
>>>> import
>>>> com.sun.grizzly.tcp.http11.GrizzlyAdapter;
>>>> import com.sun.grizzly.tcp.
>>>> http11.GrizzlyRequest;
>>>> import com.sun.grizzly.tcp.http11.
>>>> GrizzlyResponse;
>>>>
>>>> import java.io.IOException;
>>>> import java.util.
>>>> concurrent.Callable;
>>>> import java.util.concurrent.
>>>> ScheduledThreadPoolExecutor;
>>>> import java.util.concurrent.TimeUnit;
>>>>
>>>> import java.util.concurrent.atomic.AtomicInteger;
>>>>
>>>> /**
>>>> * Created by
>>>> IntelliJ IDEA.
>>>> * User: Rama
>>>> * Date: 30-ott-2009
>>>> * Time: 11.49.46
>>>> */
>>>>
>>>> public class DemoWebServer  {
>>>>
>>>>   static final AtomicInteger req = new
>>>> AtomicInteger();
>>>>   public static void main(String args[]){
>>>>
>>>> GrizzlyWebServer test = new GrizzlyWebServer();
>>>>         test.
>>>> addGrizzlyAdapter(new MyGrizzlyAdapter(),new String[]{"/"});
>>>>
>>>> test.addAsyncFilter(new MyAsyncFilter());
>>>>         test.
>>>> getSelectorThread().setDisplayConfiguration(true);
>>>>         try {
>>>>
>>>>           test.start();
>>>>         } catch (IOException e){
>>>>
>>>>           e.printStackTrace();  //To change body of catch statement
>>>> use File | Settings | File Templates.
>>>>         }
>>>>         while
>>>> (true) {
>>>>
>>>>             int reqn = req.get();
>>>>             System.out.
>>>> println("RE "+reqn+" MU "+(Runtime.getRuntime().totalMemory() -Runtime.
>>>> getRuntime().freeMemory()));
>>>>             try {
>>>>               Thread.
>>>> sleep(2500);
>>>>               System.gc();System.gc();System.gc();
>>>>
>>>>             } catch (Exception e) {
>>>>
>>>>             }
>>>>
>>>>
>>>>         }
>>>>   }
>>>>
>>>>
>>>>   static class MyGrizzlyAdapter extends
>>>> GrizzlyAdapter {
>>>>       public void service(GrizzlyRequest
>>>> grizzlyRequest, GrizzlyResponse grizzlyResponse) {
>>>>           try {
>>>>
>>>>               grizzlyResponse.getWriter().print("Great!");
>>>>
>>>>               req.incrementAndGet();
>>>>           } catch (IOException
>>>> e) {
>>>>
>>>>           }
>>>>       }
>>>>   }
>>>>
>>>>   static class MyAsyncFilter
>>>> implements AsyncFilter {
>>>>       private final
>>>> ScheduledThreadPoolExecutor scheduler =
>>>>
>>>> new ScheduledThreadPoolExecutor(1);
>>>>
>>>>       public boolean doFilter
>>>> (final AsyncExecutor asyncExecutor) {
>>>>           String url =
>>>> asyncExecutor.getProcessorTask().getRequestURI();
>>>>
>>>>
>>>>           //if
>>>> req url is rama, then delay the request
>>>>           if (url.contains
>>>> ("rama")) {
>>>>               scheduler.schedule(new Callable() {
>>>>
>>>>                       public Object call() throws Exception {
>>>>
>>>>                           asyncExecutor.execute();
>>>>
>>>>                           asyncExecutor.postExecute();
>>>>
>>>>                           return null;
>>>>                       }
>>>>
>>>>               }, 10, TimeUnit.MILLISECONDS);
>>>>               return
>>>> false;
>>>>           }
>>>>
>>>>           //if not, let them pass :)
>>>>
>>>>           try {
>>>>            asyncExecutor.execute();
>>>>
>>>> asyncExecutor.postExecute();
>>>>           } catch (Exception e) {
>>>>
>>>>
>>>>           }
>>>>
>>>>           return false;
>>>>       }
>>>>   }
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Passa a Tiscali Tutto Incluso Light: telefono + adsl 8 Mb senza
>>>> limiti a soli 9,95 euro al mese fino al 01/04/2010. Gratis la Sim
>>>> Tiscali Mobile con 25 euro di traffico.  L’offerta è valida solo se
>>>> attivi entro il 29/10/09  
>>>> http://abbonati.tiscali.it/telefono-adsl/prodotti/tc/tuttoincluso_light/?WT.mc_id=01fw 
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe@...
>>>> For additional commands, e-mail: dev-help@...
>>>>
>>> ------------------------------------------------------------------------
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@...
>>> For additional commands, e-mail: dev-help@...
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@...
>> For additional commands, e-mail: dev-help@...
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@...
> For additional commands, e-mail: dev-help@...
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@...
For additional commands, e-mail: dev-help@...