Transient with Disposable Reference kept in container

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

Transient with Disposable Reference kept in container

by jnapier :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


I have read plenty of info about transient instances and how they are
handled by the container.  I have come to believe that these were the
general rules:

1) transient non-disposable instances will not be managed by the
container and release does NOT need to be called

2) transient disposable instance will be managed by the container and
release MUST be called

It was quite a shock to me when I released a new version of my site
with a new version of the microkernel code base and the site came
crashing down 30 minutes later with a massive memory leak.

It turns out that the container is now keeping a reference to
transient instances that reference another component that is
disposable. Is this now by design and I just happened to miss the
memo?

The following simple test fails on the latest code base, but passes on
the code base I had from last October? Any info on how I can quickly
get around this problem would be great.  Thanks.

public class Holder {
        public Dispsable DisposableReference {get; set;}
}

public class Dispsable : IDisposable {
         public void Dispose() {}
}

[Test]
public void CanReleaseEmpty() {
         var container = new WindsorContainer();
        container.AddComponentLifeStyle("holder", typeof(Holder),
LifestyleType.Transient);
        container.AddComponent("disposable", typeof(Dispsable));

        var weakHolder = new WeakReference(container.Resolve<Holder>());
        GC.Collect();
        GC.WaitForPendingFinalizers();

        Assert.IsFalse(weakHolder.IsAlive);
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To post to this group, send email to castle-project-devel@...
To unsubscribe from this group, send email to castle-project-devel+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/castle-project-devel?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Transient with Disposable Reference kept in container

by Jonathon Rossi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The quick fix is to use NoTrackingReleasePolicy. See the following links for more information:

http://www.castleproject.org/container/documentation/trunk/advanced/releasepolicy.html
http://stackoverflow.com/questions/132940/why-does-castle-windsor-hold-onto-transient-objects
http://weblogs.asp.net/stefansedich/archive/2008/11/05/avoid-memory-leaks-when-using-windsor-and-not-releasing-objects.aspx

On Thu, Nov 5, 2009 at 5:44 PM, Jesse <jnapier@...> wrote:

I have read plenty of info about transient instances and how they are
handled by the container.  I have come to believe that these were the
general rules:

1) transient non-disposable instances will not be managed by the
container and release does NOT need to be called

2) transient disposable instance will be managed by the container and
release MUST be called

It was quite a shock to me when I released a new version of my site
with a new version of the microkernel code base and the site came
crashing down 30 minutes later with a massive memory leak.

It turns out that the container is now keeping a reference to
transient instances that reference another component that is
disposable. Is this now by design and I just happened to miss the
memo?

The following simple test fails on the latest code base, but passes on
the code base I had from last October? Any info on how I can quickly
get around this problem would be great.  Thanks.

public class Holder {
       public Dispsable DisposableReference {get;      set;}
}

public class Dispsable : IDisposable {
        public void Dispose() {}
}

[Test]
public void CanReleaseEmpty() {
        var container = new WindsorContainer();
       container.AddComponentLifeStyle("holder", typeof(Holder),
LifestyleType.Transient);
       container.AddComponent("disposable", typeof(Dispsable));

       var weakHolder = new WeakReference(container.Resolve<Holder>());
       GC.Collect();
       GC.WaitForPendingFinalizers();

       Assert.IsFalse(weakHolder.IsAlive);
}




--
Jono

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To post to this group, send email to castle-project-devel@...
To unsubscribe from this group, send email to castle-project-devel+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/castle-project-devel?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Transient with Disposable Reference kept in container

by jnapier :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Thanks Jonathon, I have seen the links you mention, but this changes
the release policy for the whole container. Wont this cause adverse
side affects for other non transient components?

Does the behavior I mentioned seem like a bug?

On Nov 5, 12:08 am, Jonathon Rossi <j...@...> wrote:

> The quick fix is to use NoTrackingReleasePolicy. See the following links for
> more information:
>
> http://www.castleproject.org/container/documentation/trunk/advanced/r...http://stackoverflow.com/questions/132940/why-does-castle-windsor-hol...http://weblogs.asp.net/stefansedich/archive/2008/11/05/avoid-memory-l...
>
>
>
>
>
> On Thu, Nov 5, 2009 at 5:44 PM, Jesse <jnap...@...> wrote:
>
> > I have read plenty of info about transient instances and how they are
> > handled by the container.  I have come to believe that these were the
> > general rules:
>
> > 1) transient non-disposable instances will not be managed by the
> > container and release does NOT need to be called
>
> > 2) transient disposable instance will be managed by the container and
> > release MUST be called
>
> > It was quite a shock to me when I released a new version of my site
> > with a new version of the microkernel code base and the site came
> > crashing down 30 minutes later with a massive memory leak.
>
> > It turns out that the container is now keeping a reference to
> > transient instances that reference another component that is
> > disposable. Is this now by design and I just happened to miss the
> > memo?
>
> > The following simple test fails on the latest code base, but passes on
> > the code base I had from last October? Any info on how I can quickly
> > get around this problem would be great.  Thanks.
>
> > public class Holder {
> >        public Dispsable DisposableReference {get;      set;}
> > }
>
> > public class Dispsable : IDisposable {
> >         public void Dispose() {}
> > }
>
> > [Test]
> > public void CanReleaseEmpty() {
> >         var container = new WindsorContainer();
> >        container.AddComponentLifeStyle("holder", typeof(Holder),
> > LifestyleType.Transient);
> >        container.AddComponent("disposable", typeof(Dispsable));
>
> >        var weakHolder = new WeakReference(container.Resolve<Holder>());
> >        GC.Collect();
> >        GC.WaitForPendingFinalizers();
>
> >        Assert.IsFalse(weakHolder.IsAlive);
> > }
>
> --
> Jono
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To post to this group, send email to castle-project-devel@...
To unsubscribe from this group, send email to castle-project-devel+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/castle-project-devel?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Transient with Disposable Reference kept in container

by William C. Pierce :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey Jesse,
It is not a bug.  This functionality exists to support the following scenario:

You have service, IService, implemented as such:

class ServiceImpl : IService, IDisposable {}

You register ServiceImpl as a Transient component in your container.

You have another component with a dependency on IService:

class MyComponent { public MyComponent(IService service) {} }

You register MyCompnent as a Transient component in your container.

MyComponent has no knowledge of the fact that the implementation of IService needs to be disposed.  When you resolve an instance of MyCompnent from the container, the container it is aware of this fact and tracks that instance so that when you later release it, the IService dependency is properly disposed.

Does that make sense?

It is a good practice to always release components that you have resolved.

On Thu, Nov 5, 2009 at 7:44 AM, Jesse <jnapier@...> wrote:

Thanks Jonathon, I have seen the links you mention, but this changes
the release policy for the whole container. Wont this cause adverse
side affects for other non transient components?

Does the behavior I mentioned seem like a bug?

On Nov 5, 12:08 am, Jonathon Rossi <j...@...> wrote:
> The quick fix is to use NoTrackingReleasePolicy. See the following links for
> more information:
>
> http://www.castleproject.org/container/documentation/trunk/advanced/r...http://stackoverflow.com/questions/132940/why-does-castle-windsor-hol...http://weblogs.asp.net/stefansedich/archive/2008/11/05/avoid-memory-l...
>
>
>
>
>
> On Thu, Nov 5, 2009 at 5:44 PM, Jesse <jnap...@...> wrote:
>
> > I have read plenty of info about transient instances and how they are
> > handled by the container.  I have come to believe that these were the
> > general rules:
>
> > 1) transient non-disposable instances will not be managed by the
> > container and release does NOT need to be called
>
> > 2) transient disposable instance will be managed by the container and
> > release MUST be called
>
> > It was quite a shock to me when I released a new version of my site
> > with a new version of the microkernel code base and the site came
> > crashing down 30 minutes later with a massive memory leak.
>
> > It turns out that the container is now keeping a reference to
> > transient instances that reference another component that is
> > disposable. Is this now by design and I just happened to miss the
> > memo?
>
> > The following simple test fails on the latest code base, but passes on
> > the code base I had from last October? Any info on how I can quickly
> > get around this problem would be great.  Thanks.
>
> > public class Holder {
> >        public Dispsable DisposableReference {get;      set;}
> > }
>
> > public class Dispsable : IDisposable {
> >         public void Dispose() {}
> > }
>
> > [Test]
> > public void CanReleaseEmpty() {
> >         var container = new WindsorContainer();
> >        container.AddComponentLifeStyle("holder", typeof(Holder),
> > LifestyleType.Transient);
> >        container.AddComponent("disposable", typeof(Dispsable));
>
> >        var weakHolder = new WeakReference(container.Resolve<Holder>());
> >        GC.Collect();
> >        GC.WaitForPendingFinalizers();
>
> >        Assert.IsFalse(weakHolder.IsAlive);
> > }
>
> --
> Jono



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To post to this group, send email to castle-project-devel@...
To unsubscribe from this group, send email to castle-project-devel+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/castle-project-devel?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Transient with Disposable Reference kept in container

by jnapier :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Hi Bill. It partially makes sense to me if ServiceImp is transient.
However,  I thought we were using an Inversion of Control Container
here. If I'm transparently getting my dependencies injected, why would
I ever reference the IOC container and call release on them? So much
for keeping the container transparent.

In your example ServiceImpl is transient, what if ServiceImpl isnt
transient? Why does the container need to keep track of MyComponent in
a scenario like that?


On Nov 5, 8:02 am, Bill Pierce <wcpie...@...> wrote:

> Hey Jesse,
> It is not a bug.  This functionality exists to support the following
> scenario:
>
> You have service, IService, implemented as such:
>
> class ServiceImpl : IService, IDisposable {}
>
> You register ServiceImpl as a Transient component in your container.
>
> You have another component with a dependency on IService:
>
> class MyComponent { public MyComponent(IService service) {} }
>
> You register MyCompnent as a Transient component in your container.
>
> MyComponent has no knowledge of the fact that the implementation of IService
> needs to be disposed.  When you resolve an instance of MyCompnent from the
> container, the container it is aware of this fact and tracks that instance
> so that when you later release it, the IService dependency is properly
> disposed.
>
> Does that make sense?
>
> It is a good practice to always release components that you have resolved.
>
>
>
> On Thu, Nov 5, 2009 at 7:44 AM, Jesse <jnap...@...> wrote:
>
> > Thanks Jonathon, I have seen the links you mention, but this changes
> > the release policy for the whole container. Wont this cause adverse
> > side affects for other non transient components?
>
> > Does the behavior I mentioned seem like a bug?
>
> > On Nov 5, 12:08 am, Jonathon Rossi <j...@...> wrote:
> > > The quick fix is to use NoTrackingReleasePolicy. See the following links
> > for
> > > more information:
>
> >http://www.castleproject.org/container/documentation/trunk/advanced/r....
> > ..
>
> > > On Thu, Nov 5, 2009 at 5:44 PM, Jesse <jnap...@...> wrote:
>
> > > > I have read plenty of info about transient instances and how they are
> > > > handled by the container.  I have come to believe that these were the
> > > > general rules:
>
> > > > 1) transient non-disposable instances will not be managed by the
> > > > container and release does NOT need to be called
>
> > > > 2) transient disposable instance will be managed by the container and
> > > > release MUST be called
>
> > > > It was quite a shock to me when I released a new version of my site
> > > > with a new version of the microkernel code base and the site came
> > > > crashing down 30 minutes later with a massive memory leak.
>
> > > > It turns out that the container is now keeping a reference to
> > > > transient instances that reference another component that is
> > > > disposable. Is this now by design and I just happened to miss the
> > > > memo?
>
> > > > The following simple test fails on the latest code base, but passes on
> > > > the code base I had from last October? Any info on how I can quickly
> > > > get around this problem would be great.  Thanks.
>
> > > > public class Holder {
> > > >        public Dispsable DisposableReference {get;      set;}
> > > > }
>
> > > > public class Dispsable : IDisposable {
> > > >         public void Dispose() {}
> > > > }
>
> > > > [Test]
> > > > public void CanReleaseEmpty() {
> > > >         var container = new WindsorContainer();
> > > >        container.AddComponentLifeStyle("holder", typeof(Holder),
> > > > LifestyleType.Transient);
> > > >        container.AddComponent("disposable", typeof(Dispsable));
>
> > > >        var weakHolder = new WeakReference(container.Resolve<Holder>());
> > > >        GC.Collect();
> > > >        GC.WaitForPendingFinalizers();
>
> > > >        Assert.IsFalse(weakHolder.IsAlive);
> > > > }
>
> > > --
> > > Jono- Hide quoted text -
>
> - Show quoted text -
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To post to this group, send email to castle-project-devel@...
To unsubscribe from this group, send email to castle-project-devel+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/castle-project-devel?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Transient with Disposable Reference kept in container

by Jonathon Rossi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, Nov 6, 2009 at 3:36 AM, Jesse <jnapier@...> wrote:

Hi Bill. It partially makes sense to me if ServiceImp is transient.
However,  I thought we were using an Inversion of Control Container
here. If I'm transparently getting my dependencies injected, why would
I ever reference the IOC container and call release on them? So much
for keeping the container transparent.
It still is transparent. You only need to release the root components you resolved. Windsor's mantra has always been this way, if you resolve something you release it when you are done, because you don't know if the component you'll get is disposable or what its lifestyle will be.

In your example ServiceImpl is transient, what if ServiceImpl isnt
transient? Why does the container need to keep track of MyComponent in
a scenario like that?


On Nov 5, 8:02 am, Bill Pierce <wcpie...@...> wrote:
> Hey Jesse,
> It is not a bug.  This functionality exists to support the following
> scenario:
>
> You have service, IService, implemented as such:
>
> class ServiceImpl : IService, IDisposable {}
>
> You register ServiceImpl as a Transient component in your container.
>
> You have another component with a dependency on IService:
>
> class MyComponent { public MyComponent(IService service) {} }
>
> You register MyCompnent as a Transient component in your container.
>
> MyComponent has no knowledge of the fact that the implementation of IService
> needs to be disposed.  When you resolve an instance of MyCompnent from the
> container, the container it is aware of this fact and tracks that instance
> so that when you later release it, the IService dependency is properly
> disposed.
>
> Does that make sense?
>
> It is a good practice to always release components that you have resolved.
>
>
>
> On Thu, Nov 5, 2009 at 7:44 AM, Jesse <jnap...@...> wrote:
>
> > Thanks Jonathon, I have seen the links you mention, but this changes
> > the release policy for the whole container. Wont this cause adverse
> > side affects for other non transient components?
>
> > Does the behavior I mentioned seem like a bug?
>
> > On Nov 5, 12:08 am, Jonathon Rossi <j...@...> wrote:
> > > The quick fix is to use NoTrackingReleasePolicy. See the following links
> > for
> > > more information:
>
> >http://www.castleproject.org/container/documentation/trunk/advanced/r....
> > ..
>
> > > On Thu, Nov 5, 2009 at 5:44 PM, Jesse <jnap...@...> wrote:
>
> > > > I have read plenty of info about transient instances and how they are
> > > > handled by the container.  I have come to believe that these were the
> > > > general rules:
>
> > > > 1) transient non-disposable instances will not be managed by the
> > > > container and release does NOT need to be called
>
> > > > 2) transient disposable instance will be managed by the container and
> > > > release MUST be called
>
> > > > It was quite a shock to me when I released a new version of my site
> > > > with a new version of the microkernel code base and the site came
> > > > crashing down 30 minutes later with a massive memory leak.
>
> > > > It turns out that the container is now keeping a reference to
> > > > transient instances that reference another component that is
> > > > disposable. Is this now by design and I just happened to miss the
> > > > memo?
>
> > > > The following simple test fails on the latest code base, but passes on
> > > > the code base I had from last October? Any info on how I can quickly
> > > > get around this problem would be great.  Thanks.
>
> > > > public class Holder {
> > > >        public Dispsable DisposableReference {get;      set;}
> > > > }
>
> > > > public class Dispsable : IDisposable {
> > > >         public void Dispose() {}
> > > > }
>
> > > > [Test]
> > > > public void CanReleaseEmpty() {
> > > >         var container = new WindsorContainer();
> > > >        container.AddComponentLifeStyle("holder", typeof(Holder),
> > > > LifestyleType.Transient);
> > > >        container.AddComponent("disposable", typeof(Dispsable));
>
> > > >        var weakHolder = new WeakReference(container.Resolve<Holder>());
> > > >        GC.Collect();
> > > >        GC.WaitForPendingFinalizers();
>
> > > >        Assert.IsFalse(weakHolder.IsAlive);
> > > > }
>
> > > --
> > > Jono- Hide quoted text -
>
> - Show quoted text -




--
Jono

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To post to this group, send email to castle-project-devel@...
To unsubscribe from this group, send email to castle-project-devel+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/castle-project-devel?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Transient with Disposable Reference kept in container

by William C. Pierce :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I do not recall the exact implementation of the component burden but there are many lifestyle options so even though your dependency is not transient it may possess a lifestyle that requires disposal and thus tracking.

I agree that your container should be as transparent as possible, but somewhere in your code you will always call Resolve. This call is most likely buried in the framework of your application e.g. IControllerFactory.CreateController in ASP.Net MVC.  Any instances you obtain from a call to resolve should also be released e.g. IControllerFactory.ReleaseController in ASP.Net MVC.  In my example, you would only call Release on MyComponent (because it was obtained from a call to Resolve), you would not call Release on its dependencies, that is taken care of for you...transparently.

On Thu, Nov 5, 2009 at 9:36 AM, Jesse <jnapier@...> wrote:

Hi Bill. It partially makes sense to me if ServiceImp is transient.
However,  I thought we were using an Inversion of Control Container
here. If I'm transparently getting my dependencies injected, why would
I ever reference the IOC container and call release on them? So much
for keeping the container transparent.

In your example ServiceImpl is transient, what if ServiceImpl isnt
transient? Why does the container need to keep track of MyComponent in
a scenario like that?


On Nov 5, 8:02 am, Bill Pierce <wcpie...@...> wrote:
> Hey Jesse,
> It is not a bug.  This functionality exists to support the following
> scenario:
>
> You have service, IService, implemented as such:
>
> class ServiceImpl : IService, IDisposable {}
>
> You register ServiceImpl as a Transient component in your container.
>
> You have another component with a dependency on IService:
>
> class MyComponent { public MyComponent(IService service) {} }
>
> You register MyCompnent as a Transient component in your container.
>
> MyComponent has no knowledge of the fact that the implementation of IService
> needs to be disposed.  When you resolve an instance of MyCompnent from the
> container, the container it is aware of this fact and tracks that instance
> so that when you later release it, the IService dependency is properly
> disposed.
>
> Does that make sense?
>
> It is a good practice to always release components that you have resolved.
>
>
>
> On Thu, Nov 5, 2009 at 7:44 AM, Jesse <jnap...@...> wrote:
>
> > Thanks Jonathon, I have seen the links you mention, but this changes
> > the release policy for the whole container. Wont this cause adverse
> > side affects for other non transient components?
>
> > Does the behavior I mentioned seem like a bug?
>
> > On Nov 5, 12:08 am, Jonathon Rossi <j...@...> wrote:
> > > The quick fix is to use NoTrackingReleasePolicy. See the following links
> > for
> > > more information:
>
> >http://www.castleproject.org/container/documentation/trunk/advanced/r....
> > ..
>
> > > On Thu, Nov 5, 2009 at 5:44 PM, Jesse <jnap...@...> wrote:
>
> > > > I have read plenty of info about transient instances and how they are
> > > > handled by the container.  I have come to believe that these were the
> > > > general rules:
>
> > > > 1) transient non-disposable instances will not be managed by the
> > > > container and release does NOT need to be called
>
> > > > 2) transient disposable instance will be managed by the container and
> > > > release MUST be called
>
> > > > It was quite a shock to me when I released a new version of my site
> > > > with a new version of the microkernel code base and the site came
> > > > crashing down 30 minutes later with a massive memory leak.
>
> > > > It turns out that the container is now keeping a reference to
> > > > transient instances that reference another component that is
> > > > disposable. Is this now by design and I just happened to miss the
> > > > memo?
>
> > > > The following simple test fails on the latest code base, but passes on
> > > > the code base I had from last October? Any info on how I can quickly
> > > > get around this problem would be great.  Thanks.
>
> > > > public class Holder {
> > > >        public Dispsable DisposableReference {get;      set;}
> > > > }
>
> > > > public class Dispsable : IDisposable {
> > > >         public void Dispose() {}
> > > > }
>
> > > > [Test]
> > > > public void CanReleaseEmpty() {
> > > >         var container = new WindsorContainer();
> > > >        container.AddComponentLifeStyle("holder", typeof(Holder),
> > > > LifestyleType.Transient);
> > > >        container.AddComponent("disposable", typeof(Dispsable));
>
> > > >        var weakHolder = new WeakReference(container.Resolve<Holder>());
> > > >        GC.Collect();
> > > >        GC.WaitForPendingFinalizers();
>
> > > >        Assert.IsFalse(weakHolder.IsAlive);
> > > > }
>
> > > --
> > > Jono- Hide quoted text -
>
> - Show quoted text -



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To post to this group, send email to castle-project-devel@...
To unsubscribe from this group, send email to castle-project-devel+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/castle-project-devel?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Transient with Disposable Reference kept in container

by hammett-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Thu, Nov 5, 2009 at 9:36 AM, Jesse <jnapier@...> wrote:
> In your example ServiceImpl is transient, what if ServiceImpl isnt
> transient? Why does the container need to keep track of MyComponent in
> a scenario like that?

Because you will eventually call container.Dispose when you app ends
(or some other attachment of a container instance to something
external).

If I were to rewrite Windsor, though, I'd try to stick with simplified
lifetime as transient and singleton only. Things like per-thread have
no trackable end.

--
Cheers,
hammett
http://hammett.castleproject.org/

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
To post to this group, send email to castle-project-devel@...
To unsubscribe from this group, send email to castle-project-devel+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/castle-project-devel?hl=en
-~----------~----~----~----~------~----~------~--~---