I was recently going through a garbage collection article and decided to play along and attempt to gain a greater understanding. I coded the following, playing around with the using statement, but was surprised with the results... I expected e.Parent.Name outside of the using block to go ka-blooey.
What exactly is going on here?
static void Main(string[] args)
{
Employee e = new Employee();
using (Parent p = new Parent())
{
p.Name = "Betsy";
e.Parent = p;
Console.WriteLine(e.Parent.Name);
}
Console.WriteLine(e.Parent.Name);
Console.ReadLine();
}
public class Employee
{
public Parent Parent;
}
public class Parent : IDisposable
{
public string Name;
public void Dispose()
{
Console.WriteLine("Disposing Parent");
}
}
Your Dispose method doesn't actually do anything to the instance of Parent, hence it's still fair game / works as a usable instance of a class.
IDisposable is usually used when your class holds onto an unmanaged resource, such as a database connection or a file, so that it can be cleaned up when Dispose() is called. Just calling Dispose doesn't do anything to the unmanaged resources, there has to be some code in the method that does something to those resources. Whilst c# might have the using() {} syntax to wrap instantiation and disposal of an IDisposable object in a try/catch/finally, it doesn't mean it does anything "special" with the disposed object.
Imagine, hypothetically, that Name is actually an unmanaged resource, rather than just a string, your Dispose() method could read:
public void Dispose()
{
Name = null;
Console.WriteLine("Disposing Parent");
}
Because you've assigned p to e.Parent, the object itself is still "in scope" as there's a reference to it, hence it's still accessible for Console.WriteLine(e.Parent.Name); to produce output from.
It's also currently "CLR Week" over at The Old New Thing and the first 3 articles of the week are discussing the Garbage Collector and how it works/behaves. They're well worth a read:
Everybody thinks about garbage collection the wrong way
When does an object become available for garbage collection?
Everybody thinks about CLR objects the wrong way (well not everybody)
IDisposable.Dispose is intended for you to use it to clean up unmanaged resources that you own (like file handles etc.) It doesn't do anything in its own right. The most common usage is if your class had member variables that implement IDisposable themselves, you now have responsibility for Dispose'ing them. It's just a pattern to help you, and has nothing to do with Garbage Collection - quite the opposite in fact.
The Dispose method does not destroy the object from memory. Normally a dispose method will only free up resources that it created.
Since e still exists in scope that anything associated with e (the parent assigned to e) will still exist until e is out of scope.
IDisposable is not a language feature, and does nothing special in the runtime. It is just an interface/method like any other. It happens to be a useful pattern, so they added syntax to automatically call that method in a specific pattern (using), and there are special exceptions you can throw that have "Dispose" in their name (like ObjectDisposedException).
using blocks turn from this:
using(SomeType t = new SomeType())
{
t.Something();
}
into something like this:
{
SomeType t;
try
{
t = new SomeType();
t.Something();
}
finally
{
t.Dispose();
}
}
There is absolutely no way to force the GC to collect anything. If there are references to your object somewhere in the stack (ignoring unsafe and C++/CLI code), or chained references to it from some object on the stack, then your object will live.
If you want that code to blow up, you can do something like this:
public class Parent : IDisposable
{
public string Name
{
get
{
AssertNotDisposed();
return name;
}
set
{
AssertNotDisposed();
name = value;
}
}
public void Dispose()
{
AssertNotDisposed();
Console.WriteLine("Disposing Parent");
isDisposed = true;
}
private void AssertNotDisposed()
{
if(isDisposed)
throw new ObjectDisposedException("some message");
}
private string name;
private bool isDisposed = false;
}
If you're looking for another example that will blow up when trying to do something to a disposed object.
static void Main(string[] args)
{
Employee e = new Employee();
using (Parent p = new Parent("test.txt"))
{
e.Parent = p;
using ( System.IO.StreamWriter fileWriter =
new System.IO.StreamWriter(e.Parent.File))
{
fileWriter.WriteLine("Betsy");
}
}
using (System.IO.StreamWriter fileWriter =
new System.IO.StreamWriter(e.Parent.File))
{
fileWriter.WriteLine("Betsy"); //uh-oh
}
Console.ReadLine();
}
public class Employee
{
public Parent Parent;
}
public class Parent : IDisposable
{
public System.IO.FileStream File;
public Parent(string fileName)
{
File = System.IO.File.Open(fileName, System.IO.FileMode.OpenOrCreate);
}
public void Dispose()
{
((IDisposable)File).Dispose(); //or File.Close();
}
}
Related
I am coming from C++ background and would like to have some thoughts from C# (.NET) experts on the problem statement below, I am open to solution approaches but requirements are frozen.
Problem Statement:
To have a system that provides automatic cleaning of dependent objects as soon as the owning objects are deleted (bit different from what GC provides explained below.)
Dependent objects may have other references other than its owning object, but as soon as owning object is deleted the dependent objects needs to go
To be able to replace the other outstanding references with stub object (placeholder) references as the actual object no longer exit
The system needs to be object agnostic and should be able to detect references or replace them with stubs for any object inherited from System.Object (.net)
Definition of terms:
Dependent Object: An object that always needs an owner, but may be referenced by other objects as well. The Life cycle of dependent object will however be completely owned by owning object. If the owning object is deleted the dependent object must be deleted.
Stub objects These are the objects that represents the reference that got deleted.
Functional Background
To be able to support the functional requirements we need a system that will automatically clean up the dependent objects who's owner are deleted and then it would replace other references with the stub to indicate that the object it was holding has been deleted or unloaded,
To explain this with a simple example
Time T1 - Lets say we create a Line object. Since creating a line needs a start and end point it created 2 Point (Pt1 and Pt2) objects. The Point objects are marked as Dependent objects and Line Object is the Owner. So at any point of time if we delete Line it should go and delete Pt1 and Pt2.
Time T2: We create two new points Pt3 and Pt4 (these are now independent objects)
Time T3: We create a Curve object which is referencing (Pt2, Pt3 and Pt4). Here the Pt2's lifecycle is controled by Line object.
Time T4: We delete the Line object from graphics, now as a requirement this operation must go and delete Pt1 and Pt2 as they were create by Line and Line object has been deleted.
Time T5: Since curve was also referencing Pt2 hence now its geometric computation is incomplete and will be made to reference to a stub object. The Curve object will be marked as broken so that in future point of time we can edit it to refer to new point.
The key issues in having this system is that because deleting is controlled by .NET system, we do not have control over it. Any thought how this can be achieved in C# or .NET (In C++ we have complete control over memory management so it possible to determine active references from a pointer before we delete it and remove or replace them in memory).
I understand the Garbage Collector has its own tremendous benefits, but this is critical requirements which we need to support in .NET based C# model as well.
Any thought, suggestions are appreciated.
In general you can't control the deallocation of memory in C#. As suggested by Ameya, what you can do is have a "dirty" flag.
Yes I thought about the Dirty field approach, but as i have said this needs to be managed by system level. If an object is marked as Dirty other objects
Note that in .NET there are plenty of classes that do exactly this: many IDisposable classes (the ones that inherit from Stream especially!) When Dispose()d, theiy set a disposed flag to true, and in properties/methods they do a if (disposed) throw ObjectDisposedException(). In your case you shouldn't do this, you should simply return; or return (some default value);
public class ObjectWithReferences : IDisposable
{
private List<ObjectWithReferences> childs;
protected readonly ObjectWithReferences Parent;
public bool IsDisposed { get; private set; }
protected ObjectWithReferences(ObjectWithReferences parent)
{
Parent = parent;
if (parent != null)
{
parent.AddChild(this);
}
}
private void AddChild(ObjectWithReferences child)
{
if (IsDisposed)
{
child.Dispose();
return;
}
if (childs == null)
{
childs = new List<ObjectWithReferences>();
}
childs.Add(child);
}
private void DisposeChilds()
{
if (childs == null)
{
return;
}
foreach (ObjectWithReferences child in childs)
{
if (!child.IsDisposed)
{
child.Dispose();
}
}
childs = null;
}
public void Dispose()
{
if (!IsDisposed)
{
try
{
Dispose(true);
}
finally
{
try
{
DisposeChilds();
}
finally
{
IsDisposed = true;
GC.SuppressFinalize(this);
}
}
}
}
~ObjectWithReferences()
{
if (!IsDisposed)
{
try
{
Dispose(false);
}
finally
{
try
{
DisposeChilds();
}
finally
{
IsDisposed = true;
}
}
}
}
protected virtual void Dispose(bool disposing)
{
// Does nothing, not necessary to call!
}
}
Example of use:
public class ExampleRoot : ObjectWithReferences
{
public ExampleRoot() : base(null)
{
}
public void Foo()
{
if (IsDisposed)
{
return;
}
// Do Foo things
}
public void CreateChild()
{
if (IsDisposed)
{
return;
}
// Auto-adds itself!
var child = new ExampleChild(this);
}
}
public class ExampleChild : ObjectWithReferences
{
private byte[] BigBuffer = new byte[1000000];
public ExampleChild(ExampleRoot parent) : base(parent)
{
}
protected override void Dispose(bool disposing)
{
// The ExampleChild object has a very long possible lifetime,
// because it will live even in the IsDisposed == true state,
// so it is better to free even managed resources.
BigBuffer = null;
}
}
The code is quite simple/clear... There are two example classes (a Root and a Child). The basic idea is a "special" object, ObjectWithReferences that keeps the references of its childs. It is IDisposable, and when Dispose() is called (or when it is finalized) it Dispose() all its child objects. You can inherit from this object with your classes. Everyone of your methods/properties should always check the IsDisposed property to see if the object has been disposed. If it has been disposed, they should do nothing and return default values (0, null, string.Empty, ...). Note that if one of this objects keeps references to big managed objects (arrays for example), contrary to suggested .NET guidelines, it should null these references to let the GC collect them.
Note that it is the constructor that adds the object that is being built to its parent!
The normal thing to do here would be to use a WeakReference.
If you need the stub behaviour to be automatic, you could do something like:
public class AutoStubbed<T> where T:class
{
private WeakReference<T> _reference;
private T _stub;
private readonly Func<T> _stubFactory;
public AutoStubbed(T value, T stub)
{
_reference = new WeakReference<T>(value);
_stub = stub;
}
public AutoStubbed(T value, Func<T> factory)
{
_reference = new WeakReference<T>(value);
_stubFactory = factory;
}
public T Target
{
get
{
T ret;
if(_reference.TryGetTarget(out ret))
return ret;
if(_stub == null && _stubFactory != null)
_stub = _stubFactory();
return _stub;
}
}
}
And type T to a interface both your object and your stub defines, rather the type of the object.
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.
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.
Suppose, I have following classes:
public class DisposableObj : IDisposable
{
public ChildObj CreateObj();
internal object GetSomething();
// ...
}
public class ChildObj
{
private DisposableObj m_provider;
public void DoSomething()
{
m_provider.GetSomething();
}
// ...
}
It's possible that at some point the disposable object will be disposed but child object will still have a reference to it.
If at this time user will call DoSomething method then child object will try to access disposed object. This is not good hence the question:
How should I properly design such classes?
UPDATE/CLARIFICATION:
I am aware of ObjectDisposedException and all. My question probably should sound like: how to properly notify user about exceptional situation and how design the classes to make maintaining them easier?
While that is a scenario that is technically possible, this should be an exceptional state in your progam - I can't imagine why you would deliberately set up for this scenario.
Having said, that make it clear in your design who is responsible to dispose DisposableObj and when - if any child accesses the disposed object afterwards you can argue that this should cause an exception - don't work around this but throw an exception an let the exception bubble up so you can fix the logic when you discover the problem.
Implementation-wise you can achieve this by just keeping a boolean that keeps track of whether DisposableObj is disposed and on a later access just throw ObjectDisposedException. To clarify I mean the DisposableObj object itself should keep track of its state and throw ObjectDisposedException on any method call on it after it was disposed.
First thougth that comes to mind:
Provide your ChildObj class with an internal boolean property called ProviderDisposed.
Set this property to true from Dispose in your DisposableObj
However you should keep a list of the objects created to comunicate to each one the disposed state of your main object.
List<ChildObj> childsCreated = new List<ChildObj>();
public ChildObj CreateObj()
{
ChildObj obj = new ChildObj();
childsCreated.Add(obj);
return obj;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
if(disposing)
{
foreach(ChildObj obj in childsCreated)
obj.ProviderDisposed = true;
childsCreated = null;
}
disposed = true;
}
}
public class ChildObj
{
private DisposableObj m_provider;
private bool m_providerDisposed = false;
public bool ProviderDisposed
{ set { m_providerDisposed = true; } }
public void DoSomething()
{
if(m_providerDisposed == false)
m_provider.GetSomething();
// else // as from **#BrokenGlass answer**
// throw new ObjectDisposedException();
}
// ...
}
Does the following code render the using(...) function/purpose irrelevant?
Would it cause a deficiency in GC performance?
class Program
{
static Dictionary<string , DisposableClass> Disposables
{
get
{
if (disposables == null)
disposables = new Dictionary<string , DisposableClass>();
return disposables;
}
}
static Dictionary<string , DisposableClass> disposables;
static void Main(string[] args)
{
DisposableClass disposable;
using (disposable = new DisposableClass())
{
// do some work
disposable.Name = "SuperDisposable";
Disposables["uniqueID" + Disposables.Count] = disposable;
}
Console.WriteLine("Output: " + Disposables["uniqueID0"].Name);
Console.ReadLine();
}
}
class DisposableClass : IDisposable
{
internal string Name
{
get { return myName; }
set { myName = value; }
}
private string myName;
public void Dispose( )
{
//throw new NotImplementedException();
}
}
Output: SuperDisposable
My understanding of the using(...) function is to immediately coerce disposal of the DisposableClass. Yet within the code block, we are adding the class to a dictionary collection. My understanding is that a class is inherently a reference type. So my experiment was to see what would happen to the disposable object added to a collection in this manner.
In this case DisposableClass is still quite alive. Classes are a reference type - so my assumption then became that the collection is not simply referencing this type, but indeed holding the class as a value. But, that didn't make sense either.
So what is really going on?
EDIT: modified code with output to prove that the object is not dead, as might be suggested by some answers.
2nd EDIT: what this comes down to as I've gone through some more code is this:
public void Dispose( )
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool dispose)
{
if (!isDisposed)
{
if (dispose)
{
// clean up managed objects
}
// clean up unmanaged objects
isDisposed = true;
}
}
~DisposableClass( )
{ Dispose(false); }
Stepping through the code (had a breakpoint at private void Dispose(bool dispose)), where false is passed to the method, it becomes imperative that resources are properly disposed of here. Regardless, the class is still alive, but you are definitely setting yourself up for exceptions. Answers made me more curious...
Disposing an object does not destroy it; it simply tells it to clean up any unmanaged resources it uses as they are no longer needed. In your example, you're creating a disposable object, assigning to a dictionary, and then just telling it to remove some resources.
The correct scenario for the using statement is when you want to initialize a resource, do something with it, and then destroy it and forget about it; for example:
using (var stream = new FileStream("some-file.txt"))
using (var reader = new StreamReader(stream))
{
Console.Write(reader.ReadToEnd());
}
If you want to retain the object after you've used it, you shouldn't be disposing it, and hence a using statement should not be used.
You should not be using a using block in this case, since you need the object after the block has finished. It is only to be used when there is a clear starting and ending point of the lifetime of the object.
It's important to remember that IDisposable, while a slightly special interface, is an interface nonetheless. When the using block exits, it calls Dispose() on your object. Nothing more. Your reference is still valid and, if your Dispose method does nothing, your object will be completely unaffected. If you don't keep track the disposal and explicitly throw exceptions, then you won't get any exceptions after that point because there is no inherent disposed state in .NET.
The IDisposable interface indicates that a type manages some kind of resource. The Dispose method exists to allow you to dispose of the resources used by an instance without having to wait for garbage-collection to take place and the resources to be freed by a finalizer.
In your example, the dictionary is still containing a reference to the disposable class, but the instance will have been disposed at the end of the using block. Subsequent attempts to call methods on the instance will now likely throw ObjectDisposedException or InvalidOperationException, to indicate the instance is no longer in a "working" state.
Disposing an IDisposable is not to be confused with releasing the memory occupied the instance, or invoking any garbage-collection routines on it. The instance is tracked and managed by the garbage-collector like any other, only to be released when the garbage-collector decides it.