Garbage Collection for List Objects - c#

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.

Related

Should I dispose old object before assigning new object?

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.

C# Destructor not calling after out of scope

I have problem with destructor after going out of scope(it is calling but after some time and need to make an action on form, for example change radio button), maybe there's mistake in my code. Take a look:
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
EventLogger.Print += delegate(string output)
{ if (!textBox1.IsDisposed) this.Invoke(new MethodInvoker(() => textBox1.AppendText(output + Environment.NewLine)), null); };
}
private void button1_Click(object sender, EventArgs e)
{
TestClass test = new TestClass();
}
}
public static class EventLogger
{
public delegate void EventHandler(string output);
public static event EventHandler Print;
public static void AddLog(String TextEvent)
{
Print(TextEvent);
}
}
public class TestClass
{
public TestClass()
{
EventLogger.AddLog("TestClass()");
}
~TestClass()
{
EventLogger.AddLog("~TestClass()");
}
}
}
Right, because this isn't C++. The finalizer (not destructor as in C++) is not guaranteed to be called immediately after an object has left its declaring scope, it is called when the GC decides to swoop in and clean up after you.
May I ask why you are using a finalizer to begin with? Are you maintaining references to unmanaged resources which need to be deallocated as deterministically as possible (if so, read up on the IDisposable interface)? The use cases for C# finalizers are few and far between, it's not common to implement them.
C# is not C++. Destructors don't run synchronously.
There is no bugs in your code as is, but it looks like you may need to implement "IDisposable pattern" for your class to provide a way for caller to guaranty that some destruction of your object is executed synchronously.
For those of us who are more comfortable with the C++ pattern it's useful to check out the docs for the IDisposable interface:
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
Unfortunately I've just tried it and it's not working as I'd like. I used an automatic object to save the current state of the GUI cursor, switch to the wait cursor and restore the original cursor as the object goes out of scope. The IDisposable interface does result in the cursor being restored but not immediately - so the Wait Cursor is showing for too long. Too bad because this is a very useful pattern.
Update: The C# try/finally pattern is comfortable enough after a while:
public void do_something_time_consuming()
{
ShowBusyCursor cursor = new ShowBusyCursor();
try
{
...
return;
}
finally
{
cursor.done();
}
}
The finalizer is not designed to be called immediately after going out of scope. It is called when the object is garbage-collected, which be may anywhere from milliseconds to days after going out of scope.
The finalizer is NOT meant for this kind of code. It is only for resource cleanup.
You can't force it to do something immediately after going out of scope, but you can tell it to immediately before going out of scope, with a Close() or similar method to signal that the object is done being used.
For example:
private void button1_Click(object sender, EventArgs e)
{
TestClass test = new TestClass();
// do stuff
test.Close();
}
Note: You could implement IDisposable, as has been suggested, but this use doesn't exactly fit the intended use of IDisposable, so although it would work, it's a bit hackish.

Object doesn't get garbage collected

I think this is a C# beginner question, but I can't seem to find a correct solution.
I have a ClassOne object, which defines an event.
I create a ClassTwo object, which is considered as a black box, which means I don't know whether it will register to any event or not. ClassTwo constructor registers to the event of ClassOne.
The problem comes, when ClassTwo object goes out of scope. The garbage collector never deletes this object, because it never deregistered the event.
So I have two questions:
Is there a way for ClassTwo object to know, when it goes out of scope? For an old C++ programmer this would be in the destructor, but with C# this doesn't work.
Is there a debug tool which helps me to find such objects?
Here is a sample code to reproduce the issue:
public partial class MainWindow : Window
{
static public ClassOne classOne = new ClassOne();
public MainWindow()
{
InitializeComponent();
ClassTwo classtwo = new ClassTwo();
}
private void buttonTest_Click(object sender, RoutedEventArgs e)
{
GC.Collect();
}
}
public class ClassOne
{
public ClassOne()
{
Trace.WriteLine(this + " constructor");
}
~ClassOne()
{
Trace.WriteLine(this + " destructor");
}
public delegate void UpdateFunc(object sender, EventArgs args);
public event UpdateFunc OnUpdate;
}
public class ClassTwo
{
public ClassTwo()
{
Trace.WriteLine(this + " constructor");
MainWindow.classOne.OnUpdate += new ClassOne.UpdateFunc(classOne_OnUpdate);
}
void classOne_OnUpdate(object sender, EventArgs args)
{
throw new NotImplementedException();
}
~ClassTwo()
{
Trace.WriteLine(this + " destructor");
}
}
I would implement IDisposable on an object like this and unregister from the event in the Dispose method.
You would use your object like this:
using(var two = new ClassTwo(classOne))
{
// Do something with two
}
// object can now be garbage collected.
If the caller fails to call Dispose, you are out of luck.
Not unless it implements IDisposable and the caller cooperates by calling Dispose correctly.
(Of course, why wouldn't the caller cooperate?)
Not that I've of. :( I think your best bet is to implement IDisposable and unregister on Dispose.
As other people have mentioned, the Dispose pattern is the way to address this issue. If the ClassTwo object lives for a short time, you can use the C# using statement to ensure Dispose is called after you are finished using the object:
using (var foo = new ClassTwo())
{
foo.Bar();
}
In order to find the root cause of such issues, you need to use a memory profiler. dotTrace has already been mentioned, and another good one is the SciTech Memory Profiler. What you need to find is the Root Path to the object that you think should be garbage collected, but isn't. The root paths are the reason why the object is not being collected - because through transitive references, an object that's guaranteed to be alive (a GC Root) is referencing your object that you want to be dead.
These memory profilers are very helpful in identifying which GC roots are causing you trouble, and what the reference paths are from the root to your object. Somewhere along that root path will be a reference that is out of place, and is the cause of the problem.
In your code, the cause of the ClassTwo object not being collected could be either the fact that MainWindow has a static reference to the ClassOne object, or that the event handler from ClassOne to ClassTwo has not been unhooked. Static references are one example of GC Roots - so everything classOne references will be alive until that static reference in MainWindow is changed.
Whether the static or the event handler is the problem depends on the scenario of your application - should the ClassOne object also be collected - is it wrong to have a static reference to it? Or is the static reference desired behaviour - is classOne a long lived object and classTwo a short lived one, in which case, classTwo should be Disposed when its life is over, and the Dispose should unhook the event handler.
This is a good article to learn about the .Net GC, written by Jeffrey Richter: http://msdn.microsoft.com/en-us/magazine/bb985010.aspx. It's a bit old now, there have been new additions to the GC over recent years, but it's a great place to start.

What happens with event handlers when an object goes out of scope?

Let's say we have the following setup:
public class ClassA
{
public event EventHandler SomeEvent;
}
public class ClassB : IDisposable
{
public void SomeMethod(ClassA value)
{
value.SomeEvent += (s, e) => { DoSomething(); };
}
void DoSomething() { }
void Dispose() { }
}
public static class Program
{
static void Main()
{
var a = new ClassA();
using (var b = new ClassB())
b.SomeMethod(a);
// POINT OF QUESTION!!
}
}
What happens when the event SomeEvent is raised after the "POINT OF QUESTION"?
It will call method of disposed object. That's why it is important to unsubscribe. It even can lead to memory leaks.
You should use the Dispose() method of ClassB to unsubscribe from the ClassA event. You run the risk of classes not being garbage collected which of course leads to potential memory leaks. You should always unsub from events.
Nothing you have above would unhook your event handler. Since both a and b go out of scope at the same time, you'd be safe. Since a and b can both be collected, then a will not keep b alive.
If you were to raise the ClassA.SomeEvent event after your using statement, then ClassB.DoSomething will be called even though b has been disposed. You would have to explicitly remove the event handler in this case.
If you were to retain a reference to a somewhere else, then b would be keep alive by a. Again, because the event handler has not been removed.
Nothing. Runtime doesn't know about Dispose method and call to this method inside using statement do nothing to memory management.
Garbage collection is all about memory management, but IDisposable (and Finalizer) is about resource management, so you still should think yourself and implement it manually (and propertly, for example unsubscribe in Dispose).

C# Memory allocation/de-allocation question regarding scope

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();
}
}

Categories