I see! So if that's the case, is there a real benefit from IO controller
thread? What would stop you replacing it with some other construct that
feeds into the queues directly?

On 23 June 2012 22:34, Jerome Louvel <[email protected]> wrote:

> That’s the way it already works indeed! There is just one IO controller
> thread that communicates with a pool of worker threads via a set of message
> queues, managed at the connector helper level. The wakeup issue here is
> only relevant for the IO controller thread to prevent it from spinning over
> and over.****
>
> ** **
>
> Best regards,****
>
> Jerome****
>
> --****
>
> http://www.restlet.com****
>
> http://twitter.com/#!/jlouvel****
>
> ** **
>
> ** **
>
> *De :* Ioannis Mavroukakis [mailto:[email protected]]
> *Envoyé :* samedi 23 juin 2012 13:47
>
> *À :* [email protected]
> *Objet :* Re: Idling app has ~2MB of garbage collected every 30 seconds***
> *
>
> ** **
>
> Cool, so in essence you wouldn't need to rely on interrupts to serve an
> incoming request, is that correct?****
>
> On 23 June 2012 21:41, Jerome Louvel <[email protected]> wrote:***
> *
>
> Hi Ioannis,****
>
>  ****
>
> Actually, we use several queues down the road to process the messages
> (requests and responses), so it already almost works like you expect. See
> diagrams here:****
>
> http://wiki.restlet.org/developers/172-restlet/g1/354-restlet.html****
>
>  ****
>
> Best regards,****
>
> Jerome****
>
> --****
>
> http://www.restlet.com****
>
> http://twitter.com/#!/jlouvel****
>
>  ****
>
>  ****
>
>  ****
>
>  ****
>
> *De :* Ioannis Mavroukakis [mailto:[email protected]]
> *Envoyé :* samedi 23 juin 2012 13:11****
>
>
> *À :* [email protected]
> *Objet :* Re: Idling app has ~2MB of garbage collected every 30 seconds***
> *
>
>  ****
>
> Well I'm speculating here as I haven't seen the code, but it *sounds like*
> a classic producer/consumer scenario, which might be best served with a
> blocking queue. So at one end you'd have your NIO selector or whatever
> else feeding the queue, and at the other end, a consumer picking up jobs
> via either take() or poll() (which blocks if there's no element to be
> taken).The cool thing about this, is that it promotes work stealing, so you
> could have multiple queues and consumers, which can steal work from other
> queues when idle.****
>
> As I forewarned, I haven't delved deep into the code, so I may be talking
> out of my ass :)****
>
>  ****
>
> Cheers,****
>
> Ioannis****
>
> On 22 June 2012 17:41, Jerome Louvel <[email protected]> wrote:***
> *
>
> Hi Ioannis,
>
> Regarding the GC of iterators, I've fixed the one under our control in RF
> 2.1 and 2.2/master branches yesterday. The second one is inside the NIO
> selector code so we can't remove it, which leads to the second solution
> anyway. I've also started to implement the notification/wakeup logic but
> haven't got it done yet.
>
> This takes us back to you remark. The NIO Selector#select method is here
> to allow a single thread to handle thousands of concurrent connections in a
> scalable manner. You register for IO interest for specific
> channels/connections and wait for it to return and tell you the selected
> one that are ready for processing.
>
> Could you explain a bit more about a blocking queue could help us solve
> this issue?****
>
>
> Best regards,
> Jerome
> --
> http://www.restlet.com
> http://twitter.com/#!/jlouvel
>
>
>
> -----Message d'origine-----
> De : Ioannis Mavroukakis [mailto:[email protected]]****
>
> Envoyé : vendredi 22 juin 2012 01:17****
>
> À : [email protected]
> Objet : Re: Idling app has ~2MB of garbage collected every 30 seconds
>
> Hi Jerome ,
>
> You're welcome, it's an interesting discussion. Is interrupting the
> cleanest way of doing this ? Wouldn't a blocking queue serve better in the
> context of a producer/consumer scenario?
>
> On 22 Jun 2012, at 00:31, Jerome Louvel <[email protected]> wrote:
>
> > Hi Yan, Ioannis,
> >
> > Thanks for pointing your finger on this hot spot! The GC overhead is
> > clearly an issue that needs to be fixed and definitely worth a ticket in
> GitHub.
> >
> > A first and easy solution is to replace those two iterator objects
> > with regular loops to prevent unnecessary garbage collection.
> >
> > The second and harder solution will require to have the controller
> > thread sleep by default (as long as possible to prevent unnecessary
> > CPU cycles) and indeed interrupt it when an event occurs:
> >  1) NIO event detected
> >  2) Connection event detected (new connection/message/entity chunk to
> > process)
> >
> > See this wiki pages to details on this connector and the pending tasks:
> > http://wiki.restlet.org/developers/172-restlet/g3/354-restlet.html
> >
> > Best regards,
> > Jerome
> > --
> > http://www.restlet.com
> > http://twitter.com/#!/jlouvel
> >
> >
> > -----Message d'origine-----
> > De : Ioannis Mavroukakis [mailto:[email protected]] Envoyé :
> > jeudi 21 juin 2012 01:05 À : [email protected] Objet : Re:
> > Idling app has ~2MB of garbage collected every 30 seconds
> >
> > Yes it could but you would you not end up having the overhead of
> > context switching from the thrown thread interrupts? On a low resource
> > device this can't be the best of situations I imagine.
> >
> > On 21 Jun 2012, at 00:16, Yan Zhou <[email protected]> wrote:
> >
> >> Any objections if the following is added as a new issue in the issue
> > tracker?
> >>
> >> I am thinking that the selectKeys(sleepTime) call below really should
> >> be
> > able to return immediately (thread interrupted, for example) if there
> > has been a connection state change that needs attention. The sleepTime
> > will then have little effect on how soon or how often
> controlConnections() is run.
> >>
> >> Thanks,
> >> Yan Zhou
> >>
> >>> Hi,
> >>>
> >>> We are noticing that an idling Restlet server has about 2MB of
> >>> garbage
> > collected in 30 seconds.
> >>>
> >>> I think I tracked it down to the loop in ConnectionController that
> > invokes the method below:
> >>>
> >>>
> >>>   @Override
> >>>   protected void doRun(long sleepTime) throws IOException {
> >>>       super.doRun(sleepTime);
> >>>       registerKeys();
> >>>       updateKeys();
> >>>       selectKeys(sleepTime);
> >>>       controlConnections();
> >>>   }
> >>>
> >>> The sleepTime comes from the controllerSleepTimeMs parameter, which
> >>> is 1
> > by default.
> >>>
> >>> So if the loop generates 60 bytes of garbage (2 iterator objects),
> >>> it'd
> > lead to: 60 x 1000 x 30 = 1,800,000 bytes or 1.8MB every 30 seconds.
> >>>
> >>> Can I ask if this is a known issue? And if there are workarounds?
> >>>
> >>> I have already tried tweaking the controllerSleepTimeMs and changing
> >>> it
> > to something like 30000 (30 seconds). Every connection then takes up
> > to 30 seconds to close - probably not acceptable as a solution.
> >>>
> >>> Additional info: Restlet 2.1 rc4 Android edition.
> >>>
> >>> Thanks,
> >>> Yan Zhou
> >>
> >> ------------------------------------------------------
> >>
> > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId
> > =29722
> > 83
> >
> > ------------------------------------------------------
> > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId
> > =29723
> > 87
> >
> > ------------------------------------------------------
> > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId
> > =2972533****
>
> ------------------------------------------------------
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2972585
>
> ------------------------------------------------------
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2972655
> ****
>
>  ****
>
> ** **
>

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2972815

Reply via email to