The easiest way would be to the source distribution of River.  Unpack it
somewhere.  Modify the code and then run the ant task called "build-all" (I
think, whatever it's called it default target for the build.xml).  The
build file should be in the root of the unpacked source.

I don't think Peter created a jira fir it because I've not seen a
notification email.  I'm also unsure what code libel he's referring to.

Sent via mobile device, please forgive typos and spacing errors.

On 13 Jan 2012 12:30, "Bryan Thompson" <[email protected]> wrote:

> Peter,
>
> I would be happy to test out a fix on this.  Can you point out the
> modified line and link me to any directions on how to rebuild the necessary
> jar(s)?
>
> Did you already file an issue for this?  If not, I will file an issue and
> then update it when I test out this fix.
>
> Thanks,
> Bryan
>
> > -----Original Message-----
> > From: Peter Firmstone [mailto:[email protected]]
> > Sent: Friday, January 13, 2012 3:21 AM
> > To: [email protected]
> > Cc: Bryan Thompson; [email protected]
> > Subject: Re: [Fwd: Re: DGC threads issue]
> >
> > Ok, found the problem, when I fixed River-142, I introduced a
> > new bug, after creating a new DGC thread, I didn't set the
> > running flag to true, so each time, a new thread is created.
> >
> > Thankfully it's a very easy fix.
> >
> > Cheers,
> >
> > Peter.
> >
> > Peter Jones wrote:
> > > Peter,
> > >
> > > That internal Executor interface permits neither
> > synchronous execution in the calling thread ("this method
> > itself must not block") nor any small bound on the number of
> > Runnables that can be executed concurrently ("execution of a
> > given action must not be delayed indefinitely in order to
> > complete execution of a different action passed to a
> > different invocation of this method").  In other words,
> > concurrency-wise, it should be equivalent to "new
> > Thread(runnable, name)", or what the result of
> > j.u.c.Executors.newCachedThreadPool() would do.  Otherwise,
> > callers would not function correctly, because they expect to
> > be able to pass Runnables that execute indefinitely, not just
> > short-lived work tasks.
> > >
> > > The real purpose of this internal Executor/ThreadPool was
> > to provide an internal alternative to "new Thread(...)" that
> > takes care of certain things in common, like:
> > >
> > > - thread reuse instead of creation when reasonable (idle timeout)
> > > - but still with threads (re)named for the task being executed
> > > - insulation of any thread creation permission requirement from
> > > context calling execute (NewThreadAction)
> > > - but instead requiring direct user of thread pool to be
> > trusted not
> > > to abuse that insulation, with permission requirement for access
> > > (ThreadPoolPermission and GetThreadPoolAction)
> > > - common logging of uncaught exceptions
> > >
> > > -- Peter
> > >
> > >
> > > On Jan 12, 2012, at 7:53 PM, Peter Firmstone wrote:
> > >
> > >
> > >> ThreadPool implements the com.sun.jini.thread.Executor interface.
> > >>
> > >> Because the interface states it should not block, I think
> > the calling thread should execute the task when the thread
> > pool becomes saturated, rather than continue to create new
> > threads as per the current implementation.  This will ensure
> > that the task is completed, the calling thread, if it uses a
> > sequence of tasks with dependencies will have to ensure that
> > it submits the tasks in order.  Since only the caller knows
> > the order, it makes sense for this to be the callers
> > responsibility.  As a result the executor will honor the non
> > blocking contract.  For that reason we'll use a zero length
> > queue, probably a SynchronousQueue.
> > >>
> > >> Regards,
> > >>
> > >> Peter.
> > >>
> > >> /**
> > >> * Executor is an abstraction for a thread factory or
> > thread pool for
> > >> * executing actions asynchronously.
> > >> *
> > >> * @author    Sun Microsystems, Inc.
> > >> *
> > >> */
> > >> public interface Executor {
> > >>
> > >>   /**
> > >>    * Executes the given Runnable action asynchronously in
> > some thread.
> > >>    *
> > >>    * The implementation may create a new thread to execute
> > the action,
> > >>    * or it may execute the action in an existing thread.
> > >>    *
> > >>    * The execution of a given action must not be delayed
> > indefinitely
> > >>    * in order to complete execution of a different action
> > passed to a
> > >>    * different invocation of this method.  In other words, the
> > >>    * implementation must assume that there may be
> > arbitrary dependencies
> > >>    * between actions passed to this method, so it needs to
> > be careful
> > >>    * to avoid potential deadlock by delaying execution of
> > one action
> > >>    * indefinitely until another completes.
> > >>    *
> > >>    * Also, this method itself must not block, because it
> > may be invoked
> > >>    * by code that is serially processing data to produce
> > multiple such
> > >>    * arbitrarily-dependent actions that need to be executed.
> > >>    *
> > >>    * @param    runnable the Runnable action to execute
> > >>    *
> > >>    * @param    name string to include in the name of the
> > thread used
> > >>    * to execute the action
> > >>    */
> > >>   void execute(Runnable runnable, String name); }
> > >>
> > >> Peter Firmstone wrote:
> > >>
> > >>> Thanks Brian,
> > >>>
> > >>> Looking at our implementation code, DGC uses an Executor
> > called ThreadPool, it's javadoc states:
> > >>>
> > >>> /**
> > >>> * ThreadPool is a simple thread pool implementation of
> > the Executor
> > >>> * interface.
> > >>> *
> > >>> * A new task is always given to an idle thread, if one is
> > available;
> > >>> * otherwise, a new thread is always created.  There is no minimum
> > >>> * warm thread count, nor is there a maximum thread count
> > (tasks are
> > >>> * never queued unless there are sufficient idle threads to execute
> > >>> * them).
> > >>> *
> > >>> * New threads are created as daemon threads in the thread
> > group that
> > >>> * was passed to the ThreadPool instance's constructor.  Each
> > >>> thread's
> > >>> * name is the prefix NewThreadAction.NAME_PREFIX followed by the
> > >>> name
> > >>> * of the task it is currently executing, or "Idle" if it is
> > >>> currently
> > >>> * idle.
> > >>>
> > >>> ThreadPool predates Java 5, it looks like we can fix this
> > by using an Executor from Java 5, we can look at limiting the
> > number of threads created based on available CPU's and a
> > scaling factor and place the tasks in a BlockingQueue, so if
> > the queue is filled, it blocks.
> > >>>
> > >>> Can you report the issue as a Bug on Jira for me, I'll
> > fix this before the next release.
> > >>>
> > >>> Regards,
> > >>>
> > >>> Peter.
> > >>>
> > >>> Peter Firmstone wrote:
> > >>>
> > >>>> Hi Peter,
> > >>>>
> > >>>> I was wondering if you had any thoughts on this post
> > from Bryan on River users?
> > >>>>
> > >>>> Hope you don't mind me asking ;)
> > >>>>
> > >>>> Best Regards,
> > >>>>
> > >>>> Peter Firmstone.
> > >>>>
> > >>>>
> > -------------------------------------------------------------------
> > >>>> -----
> > >>>>
> > >>>> Subject:
> > >>>> Re: DGC threads issue
> > >>>> From:
> > >>>> Tom Hobbs <[email protected]>
> > >>>> Date:
> > >>>> Thu, 12 Jan 2012 20:45:01 +0000
> > >>>> To:
> > >>>> [email protected], [email protected]
> > >>>>
> > >>>> To:
> > >>>> [email protected], [email protected]
> > >>>>
> > >>>>
> > >>>> Hi Bryan,
> > >>>>
> > >>>> Sorry that no one got back to you about this.  I'm afraid that I
> > >>>> don't know the answer to your question, I've copied the dev list
> > >>>> into this email in case someone who monitors that list (but not
> > >>>> this one) has any ideas.
> > >>>>
> > >>>> Best regards,
> > >>>>
> > >>>> Tom
> > >>>>
> > >>>> On Thu, Jan 12, 2012 at 2:29 PM, Bryan Thompson
> > <[email protected]> wrote:
> > >>>>
> > >>>>
> > >>>>> Just to follow up on this thread myself.  I modified
> > the pattern to return a "thick" future rather than a proxy
> > for the future.  This caused the RMI call to wait on the
> > server until the future was done and then sent back the
> > outcome.  This "fixed" the DGC memory/thread leak by reducing
> > the number of exported proxies drammatically.
> > >>>>>
> > >>>>> In terms of best practices, is distributed DGC simply
> > not useful for exported objects with short life spans?  Can
> > it only be used with proxies for relatively long lived services?
> > >>>>>
> > >>>>> Thanks,
> > >>>>> Bryan
> > >>>>>
> > >>>>>
> > >>>>>
> > >>>>>> -----Original Message-----
> > >>>>>> From: Bryan Thompson
> > >>>>>> Sent: Tuesday, January 03, 2012 12:06 PM
> > >>>>>> To: [email protected]
> > >>>>>> Subject: DGC threads issue
> > >>>>>>
> > >>>>>> Hello,
> > >>>>>>
> > >>>>>> Background:
> > >>>>>>
> > >>>>>> I am seeing what would appear to be one DGC thread
> > allocated per
> > >>>>>> exported object.  This is using River 2.2 and Sun JDK
> > 1.6.0_17.
> > >>>>>> Relevant configuration parameters are below.
> > >>>>>>
> > >>>>>> I am observing problems with the DGC threads not being
> > retired on
> > >>>>>> a timely basis.  The exported objects are proxies for Futures
> > >>>>>> which are being executed on the service.  The code pattern is
> > >>>>>> such that the proxied Future goes out of lexical scope quite
> > >>>>>> quickly.  E.g., rmiCallReturningProxyForFuture().get().
> > >>>>>>
> > >>>>>> Under a modest load, a large number of such Futures
> > are exported
> > >>>>>> which results in a large number of long lived DGC
> > threads.  This
> > >>>>>> turns into a problem for the JVM due to the stack
> > allocation per
> > >>>>>> thread.  Presumably this is not good for other reasons as well
> > >>>>>> (e.g., scheduling).
> > >>>>>>
> > >>>>>> I have tried to override the leaseValue and checkInterval
> > >>>>>> defaults per the configuration options below.  I
> > suspect that the
> > >>>>>> lease interval is somehow not being obeyed, which is
> > presumably a
> > >>>>>> problem on my end.  However, I can verify that the
> > configuration
> > >>>>>> values are in fact showing up in
> > >>>>>> System.getProperties() for at least some of the JVMs involved
> > >>>>>> (the one which drives the workload and the one that I am
> > >>>>>> monitoring with the large number of DGC lease threads).
> > >>>>>>
> > >>>>>> Some questions:
> > >>>>>>
> > >>>>>> Is this one-thread-per-exported proxy the expected
> > behavior when
> > >>>>>> DGC is requested for the exported object?
> > >>>>>>
> > >>>>>> The DGC lease checker threads appear to expire ~14 -
> > 15 minutes
> > >>>>>> after I terminate the process which was originating the RMI
> > >>>>>> requests.  This is close the sum of the default
> > leaseValue (10m)
> > >>>>>> and checkInterval (5m) parameters, but maybe there is
> > some other
> > >>>>>> timeout which is controlling this?  If this is the sum
> > of those
> > >>>>>> parameters, why would the DGC lease threads live until
> > the sum of
> > >>>>>> those values?  I thought that the lease would expire after the
> > >>>>>> leaseValue (10m default).
> > >>>>>>
> > >>>>>> Can the issue I am observing be caused by a low heap
> > pressure on
> > >>>>>> the JVM to which the RMI proxies were exported?  If it
> > fails to
> > >>>>>> GC those proxies, even though they are reachable, could that
> > >>>>>> cause DGC to continue to retain those proxies on the JVM which
> > >>>>>> exported them?
> > >>>>>>
> > >>>>>> Is there any way to configure DGC to use a thread pool
> > or to have
> > >>>>>> the leases managed by a single thread?
> > >>>>>>
> > >>>>>> Is it possible that there is an interaction with the
> > useNIO option?
> > >>>>>>
> > >>>>>> Relevant options that I am using include:
> > >>>>>>
> > >>>>>>   -Dcom.sun.jini.jeri.tcp.useNIO=true
> > >>>>>>   -Djava.rmi.dgc.leaseValue=30000
> > >>>>>>   -Dsun.rmi.dgc.checkInterval=15000
> > >>>>>>   -Dsun.rmi.transport.tcp.connectionPool=true
> > >>>>>>
> > >>>>>> Thanks in advance,
> > >>>>>> Bryan
> > >>>>>>
> > >>>>>>
> > >>>>
> > >>>>
> > >>>
> > >
> > >
> > >
> >
> >

Reply via email to