You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ivy-dev@incubator.apache.org by Peter Reilly <pe...@gmail.com> on 2007/09/18 08:59:12 UTC

use of IvyContext

Hi,
I have been tracking a memory leak
(http://issues.apache.org/bugzilla/show_bug.cgi?id=42742)
and found an issue with oai.core.IvyContext.

IvyContext.setIvy(Ivy) is used in Ivy#bind(),  will this
not wipe out the current Ivy setting in a multi-project enviroment?

i.e.
  Project A:
      IvyContext.setIvy() (ivy in project A)
      ant call -> Project B
           IvyContext.setIvy() (ivy in project B)
           .endProject B
      .. back in project A
      .. here IvyContext().getIvy() will return ivy from project B.
      ant call -> Project C
           IvyContext.setIvy() (ivy in project C)
           .endProject C
      .. back in project A
      .. here IvyContext().getIvy() will return ivy from project C.

Peter

Re: use of IvyContext

Posted by Xavier Hanin <xa...@gmail.com>.
On 9/18/07, Peter Reilly <pe...@gmail.com> wrote:
>
> On 9/18/07, Xavier Hanin <xa...@gmail.com> wrote:
> > On 9/18/07, Peter Reilly <pe...@gmail.com> wrote:
> > >
> > > Hi,
> > > I have been tracking a memory leak
> > > (http://issues.apache.org/bugzilla/show_bug.cgi?id=42742)
> > > and found an issue with oai.core.IvyContext.
> > >
> > > IvyContext.setIvy(Ivy) is used in Ivy#bind(),  will this
> > > not wipe out the current Ivy setting in a multi-project enviroment?
> > >
> > > i.e.
> > >   Project A:
> > >       IvyContext.setIvy() (ivy in project A)
> > >       ant call -> Project B
> > >            IvyContext.setIvy() (ivy in project B)
> > >            .endProject B
> > >       .. back in project A
> > >       .. here IvyContext().getIvy() will return ivy from project B.
> > >       ant call -> Project C
> > >            IvyContext.setIvy() (ivy in project C)
> > >            .endProject C
> > >       .. back in project A
> > >       .. here IvyContext().getIvy() will return ivy from project C.
> >
> >
> > Indeed, this is a problem! We'd need to use a stack for this and push
> the
> > context in each Ivy method call, and pop it at the end of each of them.
> But
> > it's a lot of boilerplate code which will be cumbersome to maintain.
> Using
> > AOP for this could be a solution, but we don't to introduce a dependency
> in
> > Ivy core. But maybe some AOP framework could be used at compile time
> only.
> > Do someone has some experience with this? Or see a better solution to
> avoid
> > passing around the Ivy instance everywhere?
> >
> There is any other issue with the use of IvyContext and TheadLocal.
> It contains hard references to objects of classes within Ivy
> - MessageImpl for example. It appears the the IvyContext does
> not get GCed when the project containing IVY has gone.
>
> This happens in the following case:
>
>   Project A;
>       ant call-> Project B:
>            <taskdef ivy tasks> (AntClassLoader 1)
>               IvyContext->threadLocal->messageImpl set
>            ...
>            .endProject B
>      ..
>       ant call-> Project C:
>            <taskdef ivy tasks> (AntClassLoader 2)
>               IvyContext->threadLocal->messageImpl set
>            ...
>            .endProject C
>      ..
> In this case the ivy classes are loaded by AntClassLoder 1, and
> AntClassLoader 2,
> but it appears (using jhat on the heapdump) that the IvyContext thread
> local
> object does not get GCed, which means that the associated
> classloaders do not get GCed. With a large project, this means that
> the permmem limit is quickly reached.


Good catch! Pushing and poping the IvyContext object would help in this case
too, since it would allow to keep the environment clean after the call to
any Ivy method. Indeed we use IvyContext only within Ivy methods calls, not
to pass things between several calls. So this is definitely something we
need to investigate.

Xavier

Peter
>
> > Xavier
> >
> > Peter
> > >
> >
> >
> >
> > --
> > Xavier Hanin - Independent Java Consultant
> > http://xhab.blogspot.com/
> > http://incubator.apache.org/ivy/
> > http://www.xoocode.org/
> >
>



-- 
Xavier Hanin - Independent Java Consultant
http://xhab.blogspot.com/
http://incubator.apache.org/ivy/
http://www.xoocode.org/

Re: use of IvyContext

Posted by Peter Reilly <pe...@gmail.com>.
On 9/18/07, Xavier Hanin <xa...@gmail.com> wrote:
> On 9/18/07, Peter Reilly <pe...@gmail.com> wrote:
> >
> > Hi,
> > I have been tracking a memory leak
> > (http://issues.apache.org/bugzilla/show_bug.cgi?id=42742)
> > and found an issue with oai.core.IvyContext.
> >
> > IvyContext.setIvy(Ivy) is used in Ivy#bind(),  will this
> > not wipe out the current Ivy setting in a multi-project enviroment?
> >
> > i.e.
> >   Project A:
> >       IvyContext.setIvy() (ivy in project A)
> >       ant call -> Project B
> >            IvyContext.setIvy() (ivy in project B)
> >            .endProject B
> >       .. back in project A
> >       .. here IvyContext().getIvy() will return ivy from project B.
> >       ant call -> Project C
> >            IvyContext.setIvy() (ivy in project C)
> >            .endProject C
> >       .. back in project A
> >       .. here IvyContext().getIvy() will return ivy from project C.
>
>
> Indeed, this is a problem! We'd need to use a stack for this and push the
> context in each Ivy method call, and pop it at the end of each of them. But
> it's a lot of boilerplate code which will be cumbersome to maintain. Using
> AOP for this could be a solution, but we don't to introduce a dependency in
> Ivy core. But maybe some AOP framework could be used at compile time only.
> Do someone has some experience with this? Or see a better solution to avoid
> passing around the Ivy instance everywhere?
>
There is any other issue with the use of IvyContext and TheadLocal.
It contains hard references to objects of classes within Ivy
- MessageImpl for example. It appears the the IvyContext does
not get GCed when the project containing IVY has gone.

This happens in the following case:

  Project A;
      ant call-> Project B:
           <taskdef ivy tasks> (AntClassLoader 1)
              IvyContext->threadLocal->messageImpl set
           ...
           .endProject B
     ..
      ant call-> Project C:
           <taskdef ivy tasks> (AntClassLoader 2)
              IvyContext->threadLocal->messageImpl set
           ...
           .endProject C
     ..
In this case the ivy classes are loaded by AntClassLoder 1, and
AntClassLoader 2,
but it appears (using jhat on the heapdump) that the IvyContext thread local
object does not get GCed, which means that the associated
classloaders do not get GCed. With a large project, this means that
the permmem limit is quickly reached.

Peter

> Xavier
>
> Peter
> >
>
>
>
> --
> Xavier Hanin - Independent Java Consultant
> http://xhab.blogspot.com/
> http://incubator.apache.org/ivy/
> http://www.xoocode.org/
>

Re: use of IvyContext

Posted by Xavier Hanin <xa...@gmail.com>.
On 9/18/07, Peter Reilly <pe...@gmail.com> wrote:
>
> Hi,
> I have been tracking a memory leak
> (http://issues.apache.org/bugzilla/show_bug.cgi?id=42742)
> and found an issue with oai.core.IvyContext.
>
> IvyContext.setIvy(Ivy) is used in Ivy#bind(),  will this
> not wipe out the current Ivy setting in a multi-project enviroment?
>
> i.e.
>   Project A:
>       IvyContext.setIvy() (ivy in project A)
>       ant call -> Project B
>            IvyContext.setIvy() (ivy in project B)
>            .endProject B
>       .. back in project A
>       .. here IvyContext().getIvy() will return ivy from project B.
>       ant call -> Project C
>            IvyContext.setIvy() (ivy in project C)
>            .endProject C
>       .. back in project A
>       .. here IvyContext().getIvy() will return ivy from project C.


Indeed, this is a problem! We'd need to use a stack for this and push the
context in each Ivy method call, and pop it at the end of each of them. But
it's a lot of boilerplate code which will be cumbersome to maintain. Using
AOP for this could be a solution, but we don't to introduce a dependency in
Ivy core. But maybe some AOP framework could be used at compile time only.
Do someone has some experience with this? Or see a better solution to avoid
passing around the Ivy instance everywhere?

Xavier

Peter
>



-- 
Xavier Hanin - Independent Java Consultant
http://xhab.blogspot.com/
http://incubator.apache.org/ivy/
http://www.xoocode.org/