Using C#.
I have a MainFoo class:
class MainFoo
{
private Foo foo;
public MainFoo()
{
this.foo = new Foo();
}
public CreateNewFoo()
{
this.foo = new Foo();
}
public DoCurrentFoo()
{
this.foo.Do();
}
}
A Foo class:
class Foo
{
~Foo()
{
this.DoEnd();
}
public void Do() {}
private void DoEnd() {}
}
I want to be able to call the method DoEnd() in Foo class whenever private Foo; get's initialized again. This method DoEnd() is private and I would like to keep it that way (so not accessible from MainFoo).
Since the same Foo get's initialized again, I though the instance would loose it's reference so it would call destructor. But this gets only called when MainFoo instance lost reference.
Question: How to dispose object instance when it lost it's reference?
Destructors are not guaranteed to be called at any specific time, or even get called at all. Typically, you should not rely on destructor and should implement IDisposable and call Dispose yourself.
Most conviniently, this can be done with using(...){ }.
Getting back to your sample, you can also dispose object on assignment of property (as Jason Watkins suggested), but make sure that it is not used anywhere else.
public Foo F
{
get{return foo;}
set
{
if( foo != null)
foo.Dispose();
foo = value;
}
}
You cannot, it's the Garbage Collector's job.
From MSDN:
In C#, garbage collection is handled by the common language runtime (CLR) with similar functionality to that of the JVM. The CLR garbage collector periodically checks the memory heap for any unreferenced objects, and releases the resources held by these objects.
Related
Given the following code, should I only dispose foo when it was created by within the Bar class? Or should I always dispose foo even when it was passed to a constructor? I'm thinking I should probably add another private variable to keep track of whether Bar created foo or whether it was passed to the Bar( Foo foo ) constructor, and only dispose of foo when it was created by the public Bar( string name ) constructor.
public class Bar: IDisposable
{
private Foo foo = null;
public Bar( string name )
{
this.foo = new Foo(name);
}
public Bar( Foo foo )
{
this.foo = foo;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose( bool disposing )
{
if( disposed )
return;
if( disposing )
foo.Dispose();
this.disposed = true;
}
}
You're correct in your thinking.
If you're passed an instance of Foo from elsewhere, and dispose of it yourself, you might break code still consuming the Foo. If you create an instance of Foo but don't dispose of it, you'll hang on to the memory it consumes unnecessarily long.
So, your best option is to track whether you created the instance yourself and dispose of it if so. (You could also allow the caller to specify the behaviour, as has been mentioned in the comments.)
(Alternatively, you could not do anything, which will be more inefficient but will at least not break anything. The only solution that is likely to actively break something is if you dispose of the instance that's been passed in from elsewhere.)
Is there any classes in C# which provide shared ownership of IDisposable objects? Something like shared_ptr in c++? And if not, what are best practices here?
UPDATE
I'm writing a c++/cli wrapper over native lib. And I need release native resources (MAPI COM interfaces for example, so I need determenistic resource releasing).
Native part:
//Message.h
class Message
{ ... };
//MessageSet.h
class MessageSet
{
...
class iterator : public std::iterator<std::forward_iterator_tag, Message*>
{
...
public:
Message* operator*();
bool operator!=(const iterator& that);
iterator& operator++();
};
iterator begin();
iterator end();
};
Managed part (c++/cli):
public ref class Message
{
native::Message* inst;
public:
Message(native::Message* inst);
~Message();
!Message();
};
public ref class MessageSet : public IEnumerable<Message^>
{
native::MessageSet* inst;
public:
MessageSet(native::Message* inst);
~MessageSet();
!MessageSet();
virtual IEnumerator<Message^>^ GetEnumerator();
virtual System::Collections::IEnumerator^ EnumerableGetEnumerator() = System::Collections::IEnumerable::GetEnumerator;
};
When I use Message objects in TPL Dataflow (BroadcastBlock block i.e. there are many concurrent consumers) in C# I don't know when I should call Dispose() for these messages.
I think the best you could do is something like this:
public sealed class SharedDisposable<T> where T : IDisposable
{
public sealed class Reference : IDisposable
{
public Reference( SharedDisposable<T> owner )
{
mOwner = owner;
}
public void Dispose()
{
if( mIsDisposed ) return;
mIsDisposed = true;
mOwner.Release();
}
public T Value => mOwner.mValue;
private readonly SharedDisposable<T> mOwner;
private bool mIsDisposed;
}
public SharedDisposable( T value )
{
mValue = value;
}
public Reference Acquire()
{
lock( mLock )
{
if( mRefCount < 0 ) throw new ObjectDisposedException( typeof( T ).FullName );
mRefCount++;
return new Reference( this );
}
}
private void Release()
{
lock( mLock )
{
mRefCount--;
if( mRefCount <= 0 )
{
mValue.Dispose();
mRefCount = -1;
}
}
}
private readonly T mValue;
private readonly object mLock = new object();
private int mRefCount;
}
Basically this allows you to have one object (SharedDisposable<T>) manage the lifetime of the underlying disposable while providing a mechanism to distribute "shared" references to it.
One shortcoming here is that technically anyone could dispose the underlying value by accessing it through the shared reference Value property. You could address this by creating some sort of facade object that wraps the underlying disposable type but hides its Dispose method.
That would a NO.
Best way I found so far is quite clunky, using Dictionaries and WeakReferences. The Dictionary maps the object to it's refcount. WeakReference is used so you don't increase the ref count artificially.
You do not own IDisposable, you implement it, so .NET Garbage Collector will call overridden method in your class, notifying about a fact happened.
It's a different concept from shared_ptr, where destructor is guaranteed to be called once last ownership of a pointer is gone.
In general, in .NET, unless you are not using unsafe programming techniques, you do not own anything, .NET Garbage Collector owns it.
Even when you explicitly destroy an object, the memory allocated for it may not, and often will not, be reclaimed immediately, like once would expect from C++.
EDIT
If you have native resources and want release them in precise moment, you can achieve that by :
1) Implementing IDisposable with your .NET wrapper object
2) Inside Dispose() method of that wrapper write the code that releases native resources
3) In the code that consumes wrapper object, in the moment you would like to release native resources allocated by wrapper object, call explicitly Dispose() on it.
In this case Dispose() method is called, your code executes and releases native resources immediately.
EDIT (2)
After that is more clear what's the question about:
If you can not determine when Dispose() has to be called, I would stay with #Hans's comment: just relay on eventual (soon or later) GC call and avoid your own reference counter implementation (especially in multi threaded environment).
Do not invent the wheel, if that is a feasible in your situation.
Lets assume we have two class Foo and Bar as given below.
public class Foo
{
public static Bar BarInstance { get; set; }
public static void Main()
{
AssignBar("A");
AssignBar("B");
}
private static void AssignBar(string name)
{
BarInstance = new Bar(name);
}
}
public class Bar : IDisposable
{
public Bar(string name)
{
Name = name;
}
public string Name { get; set; }
protected virtual void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
When object A gets replaced by object B. I expect Dispose to called because since there is no reference to Object A exists any more, but it doesn't get called. Could you please explain why?
Should I end up doing CurrentBar.Dispose like below if I want Object A to be disposed.
private static void AssignBar(string name)
{
if (BarInstance != null)
{
BarInstance.Dispose();
}
BarInstance = new Bar(name);
}
It depends on the ownership.
Is Bar given to Foo with the implication that Foo now owns Bar?
If so, then yes, you should call Dispose on the old before assigning a new instance.
Is Bar given to Foo with the implication that it's more of a loan, ie. you can reference and use this object, but it is owned by something else?
If so, then no, you should not call Dispose on the old before assigning a new instance.
Your code is not altogether clear on this point and I would suggest you clean that up, would make it easier to reason about this type in the future.
The way I see it you have 1 of 3 possible scenarios:
Foo always owns Bar. In this case I would put the disposal of the old instance in the setter of the property, or remove the public setter altogether if the only way to get a new Bar instance into it is through the method you have declared.
Foo never owns Bar. In this case I would not add any code that disposes of the old instance, but then I question the existence of that method. In this case it is likely nobody would really own the newly constructed instance.
Foo only owns Bar instances created through your method, but not instances given to it through the public setter. In this case I would add a new field that tracks whether Foo owns Bar or not, and set this to true in the method, and clear it in the property setter.
Dispose is not special in any way, from the C# standpoint it is just another method, as such there is nothing automatic that will call this method.
However, if the object references unmanaged resources, when the object at some point becomes eligible for collection, its finalizer will be executed releasing those unmanaged resources. However, to deterministically release them when you know they are no longer needed, you need to call Dispose.
Dispose is no special method. It will not be called automatically. You'll have to do it.
private static void AssignBar(string name)
{
if(BarInstance!=null)
{
BarInstance.Dispose();
}
BarInstance = new Bar(name);
}
I think you are confusing with finalizers and IDisposable. Finalizers are called at the time of garbage collection(not reliable though). If you have implemented DisposablePattern, then you'll have a Dispose(bool) method which is called from finalizer. Where finalizers are called by GC automatially during garbage collection.
Read here for more info
The runtime won't automatically call Dispose for you, it's your responsibility to ensure it's called. Your object will be garbage collected, but this only ensures that memory is reclaimed. It's up to use to release resources.
You can do this using either a using statement:
using(var x = new BarInstance())
{
// Whatever
}
or you can call it yourself. In your example, since you're replacing the instance you'll need to call Dispose, otherwise you risk a resource leak.
You could opt to use a finalizer in your class, ~Bar. In the finalizer you can dispose of any resources you're holding. However, when the finalizer will be called in non-deterministic, and it's even possible that it will never be called if the garbage collector doesn't kick in.
I would like to ask what is the efficiency way the clean and dispose the object collected in the List (Of Object)?
Is that by calling the List.Clear() method will automatic clean all the object collected by it?
For Example consider the below example
public partial class Form1 : Form
{
FontCollection m_fontCollection;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
m_fontCollection = new FontCollection();
for (int i = 0; i < 5000; i++)
{
Font font = new Font("Arial", 23);
FontImpl impl = new FontImpl(font, Color.Black);
impl.AfterChange +=
new FontImpl.AfterChangeHandler(impl_AfterChange);
m_fontCollection.Add(impl);
}
m_fontCollection.Dispose();
MessageBox.Show("TakeSnap");
}
void impl_AfterChange()
{
throw new NotImplementedException();
}
}
public class FontCollection : IEnumerable, IDisposable
{
IList<FontImpl> m_Implementation = new List<FontImpl>();
internal void Add(FontImpl impl)
{
this.m_Implementation.Add(impl);
}
public IEnumerator GetEnumerator()
{
return this.m_Implementation.GetEnumerator();
}
public void Dispose()
{
m_Implementation.Clear();
m_Implementation = null;
}
}
public class FontImpl
{
private Font m_Font;
private Color m_color;
public FontImpl(Font newFont, Color newColcor)
{
m_Font = newFont;
m_color = newColcor;
}
public event AfterChangeHandler AfterChange;
public delegate void AfterChangeHandler();
}
When i run the above application ANTS memory profiler i could see the memory leaks Font and FontFamily (I could not able to upload the screen) and how to remove these leaks
In general, you shouldn't need to worry about garbage collection, and when it occurs. An object is eligible for GC when there are zero references to it.
The thing you should pay attention to, however, are IDisposable objects. When you are finished with an IDisposable object, you really need to be calling Dispose() on it. If the object lives within the local scope of a functinon, then a using block makes this easy:
using (var resource = new SomeIDisposable()) {
// use resource
// resource.Dispose() is automatically called, *even if* an exception
// is thrown.
}
You can cause memory leaks by ending up with "dangling references" to objects, which prevent them from being garbage collected. Most often the cause of this is with event handlers. When you subscribe to an event exposed by object A, with an event handler on object B, A gets a reference to B:
class B {
void hook_up_to(A a) {
a.SomeEvent += Handler; // `a` gets a reference to `this`
}
void Handler(object sender, EventArgs e) {
}
}
class Program {
private A _a = new A();
static void SomeMethod() {
var b = new B();
b.hook_up_to(_a); // _a now has a reference to b
// b goes out of scope.
}
}
Normally, when b goes out of scope, the object it references would be eligible for garbage collection. In this case though, b hooked up to an event published by member variable _a, which caused _a to gain a reference to b. Now there is one outstanding reference to b, which is impossible1 to clear, and b is ineligible for GC. This is a memory leak.
1 The only way reference to b in this case is this pointer if/when the event handler is fired.
You don't need to implement IDisposable on your class. In general the only time your class needs to implement IDisposable is when it contains other classes that need to be disposed of (things like database and network connections, and unmanaged objects).
In your example, you might want to consider making m_fontCollection a local variable within button1_Click, since you're creating and disposing of it entirely within that method. If you make it local, then it will be garbage-collected once button1_Click exits ... provided there are no remaining references to it (which indeed there are not in this case).
Clear just removes everything from the list. In your case you have a list of IDisposable objects and you need to call Dispose on all the items in the list. Calling Clear does not do that.
Your FontImpl should implement IDisposable since it manages an IDisposable object:
public void Dispose() {
if (m_Font != null) {
m_Font.Dispose();
m_Font = null;
}
}
And your FontCollection Dispose should look like this:
public void Dispose()
{
foreach(FontImpl font in m_Implementation) {
font.Dispose();
}
m_Implementation.Clear();
m_Implementation = null;
}
In the case of the code you have shown you have Font objects which implement IDisposable and thus should be disposed. Those objects are being managed by your FontImpl class and so FontImpl should implement IDisposable. Your FontCollection class contains a list of FontImpl objects which should now be disposable and so FontCollection needs to implement IDisposable.
You should read up on the IDisposable pattern (this SO answer gives some great information - https://stackoverflow.com/a/538238/416574).
That being said, from the code snippet you provided it does not appear that you gain anything from your FontCollection other than a class to wrap a list. Unless there are other things you are going to do with that class I would just have a list as a member variable. That way in the Dispose method of your form you can walk your list and dispose the FontImpl objects. If you want to protect from double disposing, then just empty the list after disposing everything.
Please see code below. The destructors are never called. Anyone know why and how this can be rectified?
public partial class Form1 : Form
{
private Goo goo;
public Form1()
{
InitializeComponent();
goo = Goo.GetInstance();
}
}
public class Goo
{
private foo f = new foo();
private static Goo goo;
private Goo()
{}
public static Goo GetInstance()
{
if(goo!=null)
{
goo = new Goo();
}
return goo;
}
~Goo()
{
}
}
class foo
{
~foo()
{
}
}
Objects referenced by static fields are not simply finalized unless you clear (set to null) the field - and even then it is non-deterministic and not guaranteed. Static fields count as root objects.
When (and why) would you expect this to be collected/finalized? It is still accessible...
Objects referenced by static fields are always reachable (assuming no class unloading or any other GC funkiness) and will never be collected.
Even though you might expect the finalizer on static objects to run when the process is shutdown, there are no guarantees there either:
http://blogs.msdn.com/cbrumme/archive/2004/02/20/77460.aspx (look at the section titled "V1 & V1.1 Finalization Guarantees"). I'm not sure how much of this has changed in .NET 2.0 or later.
That's not a destructor. It's a finalizer. That's a different thing. As the other two have said, because this is a static, it will never be collected, hence the finalizer will never run.