How to dispose heavy set of static variable and collection? - c#

I made a big windows app, and in the program.cs class i am using a lot to static variables
around 20 and some of these are used for big collection of object that i make during the process.
I want to know how should i mange this in the finish of application where and how should i call them dispose. I made GC.Collect but that hangs application and degrade the performance.
And when i dint call GC.Collect it was giving memory lick and hanging for long.
Please let me know how should i manage this static class, static variables. So that performance boost.

I think the way you are using the static variables is completely wrong, you might have misunderstood the concept.
You should mark any field as static only when you know, variables will be accessed through out the life of program i.e. they will be GC'ed only when you terminate the program.
EDIT In C# the memory is automatically managed by the Garbage Collector, the programmer need to know only that when an object which is created is applicable for Garbage Collection. In MSDN ducumentation it is clearly mentioned,
C# employs automatic memory management, which frees developers from manually allocating and freeing the memory occupied by objects. Automatic memory management policies are implemented by a garbage collector. The memory management life cycle of an object is as follows:
When the object is created, memory is allocated for it, the constructor is run, and the object is considered live.
If the object, or any part of it, cannot be accessed by any possible continuation of execution, other than the running of destructors, the object is considered no longer in use, and it becomes eligible for destruction. The C# compiler and the garbage collector may choose to analyze code to determine which references to an object may be used in the future. For instance, if a local variable that is in scope is the only existing reference to an object, but that local variable is never referred to in any possible continuation of execution from the current execution point in the procedure, the garbage collector may (but is not required to) treat the object as no longer in use.
Once the object is eligible for destruction, at some unspecified later time the destructor (Section 10.12) (if any) for the object is run. Unless overridden by explicit calls, the destructor for the object is run once only.
Once the destructor for an object is run, if that object, or any part of it, cannot be accessed by any possible continuation of execution, including the running of destructors, the object is considered inaccessible and the object becomes eligible for collection.
Finally, at some time after the object becomes eligible for collection, the garbage collector frees the memory associated with that object.
In simple words, if an object has no more live references (pointers whose scope has not ended) which are pointing to it, it is eligible for GC.
In your case the static variables are are having the scope which extends across the entire run of the program and once you remove those references either by assigning those to new objects or assigning them to null then old objects will be applicable for GC if no other live references pointing to old objects are alive.

You have IDisposable objects (Forms and Controls, I'm guessing) and need to dispose them at some appropriate time. The best way to solve this is going to be to create an object model appropriate to your domain, and have it manage them. I don't know about your domain, so it's hard to give details about that.
To make it more convenient, you could group these variables together in one class. Instead of holding these variables in the Program class, put them in another class that Program references, and make that class IDisposable. Something like this:
public class Resources : IDisposable
{
public MyForm MyForm {get;set;}
public MyControl MyControl {get;set;}
//etc...
public void Dispose()
{
if(MyForm != null)
MyForm.Dispose()
if(MyControl != null)
MyControl.Dispose()
//etc..
}
}
If the problem with this is that you want to avoid bugs around accessing Disposed objects, don't make them static! If they are not static, you can control what object bind to them more clearly, and make sure those object stop holding a reference to them when they are disposed.

Related

Minimizing usage of RAM by created objects in runtime in C#

I was wondering what are the best practices when creating objects, performing LINQ in C#. For instance, I realize that when I open up a connection using LINQ I should be putting the model object into a using statement like this:
using(var ctx = new mymodel())
{
}
Now, what about the objects that are EF classes?
They do not implement IDisposable interface thus I can't do something like this when creating an object like this for example:
using(var user = new Users())
{
}
But when an action is called like this:
public ActionResult InsertUser()
{
var user = new Users();
}
I have no clear picture what happens with this object once the insert into the db is finished. Does this object stays allocated in memory or it gets released? If not, what are best practices to release memory once they aren't needed anymore..?
On the other there are static variables as well...
So to sum things up, my questions are:
what are best practices to release memory when creating instances of an object of a class?
Is implementation of IDisposable interface on every class that I have good choice?
When a static variable is created in .NET MVC, what is the best way to release memory taken by this kind of variables?
Same question goes for Session object?
P.S. Guys, I'd really appreciate if all of you that are reading this to post your opinion or post some useful links for some documentations/blog posts so that I can expand my horizons =)
Before you do any performance tweaks I highly recommend to run a memory profiler (for example JetBrains dotMemory, but there are others) and find out the actual source of the problem. Without information from profiler, your optimisations will be like sticking your finger at a sky and shouting "Rainbow!" i.e. useless at best, harmful at worst.
Also after identifying issues with profiler, but before starting changing your code, I recommend reading about how Garbage Collection works in .Net. Here are some references to get you started:
MSDN Garbage Collection
MSDN Garbage Collector Basics and Performance Hints
.Net Garbage Collection in depth
Here are some links to answer your questions:
IDisposable vs Garbage Collector
Static vs Garbage Collector: 1, 2
Session and Garbage Collection
In response to comment.
When you create regular .NET object, .NET runtime knows everything about it, because runtime created it. It knows where in memory it's located, when it is no longer needed and so on. When it is no longer needed - runtime will reclaim its memory. That is managed (by runtime) object. You should not care about memory management for such objects.
Now take for example file handle. When you open file in .NET, it will delegate this operation to OS (for example, Windows). This resource is not managed by runtime, it is managed by OS. So, it is unmanaged resource. So author of .NET library code which works with files (I mean person who created FileStream and similar classes, not uses them) should manually write code to release such resource (close file handle in this case). By convention, author will use IDisposable.Dispose method for code that releases such resources AND ensures that when underlying object (like FileStream) will be collected by GC - unmanaged resources will also be released. So even if you forget to call Dispose - file handle will be closed when GC collects FileStream (not that it will happen not magically but because code author explicitly made it happen like this). But that might happen any time in the future, you don't want to leave file handle open for undetermined time - so you always call Dispose yourself when you are done with IDisposable object.
The same applies to most unmanaged resources. For example, database connection is managed by database, and you don't want to leave database connection open for undetermined time, so you call Dispose and explicitly notify database to close it (and even if you don't call it - author of .NET database code took care to do that when object is collected). EF context wraps database connection, so it also implements IDisposable. If you don't want to leave connection open until context will be collected (and you sure don't want that) - you call Dispose yourself.
Or suppose you write your own code to work with images using ImageMagick. That is C library, so runtime has no idea about its inner workings. You ask library to allocate memory for your image, but .NET cannot reclaim such memory - it does not manage it, it is managed by ImageMagick C library. So you implement IDisposable and tell ImageMagick to release memory in that method.
In the case of var user = new Users(); which does not implement IDisposable, and any object for that matter which is not disposed, will only be guaranteed to exist where there is an active reference to this object; after which it will qualify for disposal the next time the Garbage Collector (GC) tries to free up memory.
In your example above, as soon as this leaves the method InsertUser() it will no longer have any references pointing to it, and therefore will be up for garbage collection.
If however a reference exists, such as in the following code, the object will not be disposed until the reference is cleared, or the containing class is disposed.
private User _insertedUser;
public ActionResult InsertUser()
{
_insertedUser = new Users();
}
The garbage collector fires when the application needs to release some memory. When it fires, it performs several sweeps on objects within memory to tell if any references exist. It first scans every object which has been newly created since the last time the GC was called. Objects which survive this sweep are promoted a generation. If after the sweep more memory is still required, then a 2nd generation sweep is performed. This will scan every object which has survived a single garbage collection to see if it can now be freed. Again if an object survives, it moves up another generation, with 3 generation sweeps in total.
This method helps the GC perform memory management while limiting the high costs involved (newer objects are more likely to be available for release). As GC has a high cost associated to it, it's better if objects are disposed of through user's code to help limit the number of times the GC is called.
tldr;
Dispose objects if they implement IDisposable; an easy way is to
surround it by a 'using'.
If an object cannot be disposed, and it is no longer required, make sure all references to the object is cleared (especially references outside of a method which the object was created).
This enables the GC to release it from memory.

Why is this object not garbage collected? [duplicate]

This question already has an answer here:
When is an object subject to garbage collection?
(1 answer)
Closed 7 years ago.
I'm still somewhat confused by C#'s garbage collector. Documentation states that an object is garbage collected when there are no more references pointing to it.
So my question is, why is this object not immediately garbage collected? There is no reference to it. Let's assume that the background class itself creates no references either.
public void StartGame() {
// the background instance is created, but no reference is kept:
new Background("landscape.png", speed);
}
What you are describing is of more resemblance to memory management through reference counting, that checks whether to free the memory when the reference counter is accessed, typically when the referencing object is constructed or destroyed.
Garbage collection is a slightly different concept. Directly freeing the objects in GC-powered environments is typically not allowed or not recommended. Instead, a garbage collector is run occasionally (the runtime decides when to do that), that finds all the no longer referenced objects and frees the memory taken by these. The point is, you should not bother (because you can do nothing about it) when exactly it's going to happen.
The garbage collector is like the garbage truck that drives around your neighborhood. You can't will it to pick up your trash once you put it on the side of the street. You have to wait for it to come on its own terms.
Garbage collectors are theoretically really simple: stop the world, determine what's no longer being used, collect, resume the world. But because this takes time, developers use complex algorithms to decide when the collector kicks in and what it collects, to make your program run as smoothly as possible. Some garbage is usually not a problem that affects your program.
If you are expecting your object to be collected as soon as it goes out of scope, and you're probably using a finalizer to test this. Don't! Instead, implement IDisposable and call the Dispose method yourself, as soon as you're done with it. You can't rely on the garbage collector to collect your object at any time, if ever. That's why the BCL I/O classes all implement IDisposable for flushing streams, closing connections and cleaning up memory.
Or if you want to keep your object around, you need to keep an (indirect) reference to it. The object might just be collected on the next garbage collection cycle.
Well, there's one not recommended way to force the garbage truck to collect your garbage, using GC.Collect:
GC.Collect();
This will temporary stop your program to collect all garbage. However, this might still not clear your Background object while it's living on the stack or some other place. You can't predict where the runtime will put your object and when it will release it, so be sure to at least exit the method that created the object before testing whether it is collected using GC.Collect.
The garbage collector in C# is invoked only at certain moments and is generational. This means that an object that has no reference at the first pass of the GC will be upgraded by 1 generation. The lowest generation is garbage collected way more often than the rest.
You may read this article to understand more: https://msdn.microsoft.com/en-us/library/ee787088%28v=vs.110%29.aspx
You may alternatively call the GC.Collect method, but this is not recommended as .NET is pretty much able to handle its own memory and invoking this method kinda defeats the whole purpose.
Well if you want to check if an object will be garbage collected you can do the following to test in your code if it is eligible for collection by doing the following.
Modify your method a little for testing alternatively you could make reference a field that is set in the StartGame Method.
public void StartGame(out WeakReference reference)
{
reference = new WeakReference(new Background("landscape.png", speed));
}
After your method is called you can do the following to see if it is eligible for collection.
WeakReference reference;
StartGame(out reference);
GC.Collect();
GC.WaitForPendingFinalizers();
if (reference.IsAlive)
{
Console.WriteLine("Background is not eligible for collection");
}
This is only for testing, you shouldn't be calling the Garbage collector otherwise.

Instance variable lifetime in classes vs structs

I know that an instance variable of a class comes to life when a new instance of that class is instantiated and when there are no references to that instance, the instance's destructor has executed. But what about instance variables lifetime in structs?
Thanks.
and when there are no references to that instance, the instance's destructor has executed
Only if that class has a destructor (otherwise, its memory is simply reclaimed), if GC.SuppressFinalize hasn't been called on that object, and when the Garbage Collector decides to collect the generation to which that object belongs.
Also note that destroying an object isn't the same as reclaiming its memory.
When the GC calls an object's destructor, the object will be promoted to the next generation, and its memory will only be reclaimed the next time the GC decides to collect that generation, if there are still no strong references to it.
And this is why it's possible (but don't do it!) to resurrect an object, by creating a strong reference to itself (e.g., assigning itself to a static field) within the destructor.
But what about instance variables lifetime in structs?
If they're declared within a method and not leaked anywhere (such as using it in a closure, or being assigned to a field member), chances are they'll be put on the stack and deleted deterministically when the method ends, and the GC will never know about it.
If they're assigned to a field, they'll live as long as the enclosing class lives.
Also, structs can't have destructors.
First of all, it is not true, that if there are no references to the instance, it's destructor is being called. What really happens is that at the time of Garbage Collector's choice the object is marked as garbage and then later, again at the time of Garbage Collector's choice the object is destroyed.
In case of structures, you have to remember, that structure behaves similarly as any other value-type object (such as int, float and so on). So, for example, if you keep structure in a local variable and exit the method, structure is deleted from the stack, thus clearing all references to its all fields - and if they are reference-typed (and no other references exists), they will be collected by the GC in the same manner I described earlier. If they are value-typed, they are deleted immediately.
You can read more about this matter in article and on msdn
You should probably read up on Garbage Collection, as the assumptions you make are outright wrong. When nothing references an object, GC may collect it, but you won't know precisely when. Also, C# has no destructors, it has finalizers, which aren't deterministic as opposed to destructors. The syntax is the same as the C++ destructor, but under the hood they're different.
The difference between reference types (classes) and value types (structs), is that reference types are garbage collected if there is no valid reference to them anymore, where value types are collected when they go out of scope. Types like int, IntPtr, etc are all structs and follow the same rules.
As per MSDN:
"An instance variable of a struct has exactly the same lifetime as the struct variable to which it belongs i.e, when a variable of a struct type comes into existence or ceases to exist, so too do the instance variables of the struct."
Source: http://msdn.microsoft.com/en-us/library/aa691165(v=vs.71).aspx
(Although it is destroyed by the Garbage Collector actually).

Garbage Collection in C#

So I'm making a client program for a MySQL database for a class and I have a few variables declared at the top of my form class that I use and reuse throughout the lifespan of the form. Every time the variables get used, I'm simply doing something like:
variableName = new VariableClass();
and then using it, primarily with DataSets/Tables. What I'm wondering is should I be explicitly freeing the memory before making another call to new or does C# take care of that for me?
There is no need to explicitly free .Net objects in C#. It runs on the CLR which is a garbage collected environment and hence the items will be cleaned up for you.
That being said ... it's unclear from your question if you are allocating these as fields or locals. If you are allocating them in fields and only using them in one function then you should move that declaration to a local. While the memory won't leak you will be holding onto the objects for significantly longer than is needed. This unnecessarily increases the memory footprint of your application.
It depends upon what the class of the variables does. If it uses resources that require disposal or if it uses unmanaged resources, you should implement IDisposable and ensure that they are disposed of correctly. If not, you can rely on the garbage collector to do its thing.

Memory Leak questions

I've been reading a lot about this since I've been asked to fix a C# application that has memory leaking problems, but I haven't found an answer for these 2 issues:
Consider the following code:
private static ArrayList list = new ArrayList();
public void Function()
{
list.add(object1);
list.add(object2);
//didn't call clear() prior to reusing list
list = new ArrayList();
}
Since the list wasn't cleared before creating a new one, will this generate some sort of garbage that won't be released after the static list itself is disposed?
The second issue is regarding Form.Dispose(). I see that a lot of controls available on designer view (i.e. labels, picture boxes) require disposing. It's seems as though calling Dispose() on a Form causes all of these types of controls to be disposed also (correct me if I'm wrong), which is odd since the designer adds an overriden void Dispose(bool disposing) method which does no such thing. I'm assuming that this happens at the void Dispose(bool disposing) method of the base Form class.
The problem with the above is that it is not very clear to me what I need to do to ensure that all of the Form's resources are disposed correctly. I do not understand how the Form knows which objects it needs to dispose. For example, if in my form I have a field which is a custom IDisposable object, will the Form know that it needs disposing? Or should I add the code necessary to release the object myself?
Also, if I do need to add the code to dispose certain objects, then how do I deal with the fact that the designer has already overriden the void Dispose(bool disposing) method? Should I edit the designer generated code or is there a cleaner way to do this?
I hope that this wasn't to confusing, it's a bit hard to explain. Thanks
No, that's not a leak. When the garbage collector goes searching for object references, it won't find a reference to the original ArrayList anymore. You replaced it. So it will automatically destroy that original ArrayList object, as well as all of its elements if they are not referenced anywhere either.
The Form class knows how to dispose itself, as well as all the controls that are child windows on that form. This happens when the user closes the form, the WM_CLOSE message that Windows sends triggers this code. The Form.Controls collection helps it find the reference to all child controls so it can dispose them too.
However, this will not happen if you remove controls from the form yourself. Now it is up to you to call Dispose() on them. Particularly the Controls.Clear() method is dangerous. What is unusual about it is that this causes a permanent leak, the controls you remove are kept alive by the 'parking window'. Which keeps the window handle alive so you can move them elsewhere, on another container window for example. If you don't actually move them, they'll stay hosted on that parking window forever. No other classes in the framework quite behave this way.
This leak is easy to diagnose with Taskmgr.exe, Processes tab. View + Select Columns and tick USER Objects. If this steadily goes up while your program runs then you're leaking controls.
What is the scope of your Static arraylist. Looks to me that it has a form scope. If it is, it will not be disposed since static objects are always considered rooted and has an application life time. In my experience, statics always take more memory and get promoted to gen 2 because of this fact. If you have any doubts, take a .net memory profiler and check it out. You can also take memory dumps and analyze it using windbg to figure out the real cause of the leak.
In many memory-management frameworks, garbage-collected and otherwise, freeing up memory within an application does not generally cause the application to release that memory, but instead record the fact that the memory should be available for future requests. Part of the idea behind garbage collection is that when user code asks for memory and the application knows that it has at least that much immediately available, neither the code nor the application will care about whether any memory not needed for that request is "allocated" or "free". When the last reachable reference to an object is destroyed or becomes unreachable, the object effectively ceases to exist right then and there, but there's generally not much purpose in trying to reclaim memory formerly used by non-existent objects until such reclamation is either required to fulfill an allocation request, or the "memory freed per time spent" ratio is as good as its likely to get.
Note that for the system to reclaim the memory associated with an object, it is absolutely imperative that no reference of any sort exist to that object. If there exist any reachable weak references to an object which is not otherwise reachable, the garbage-collector must invalidate all such references (so they no longer identify the object) before the space used by the object can be reclaimed. If an otherwise-unreachable object has a registered finalizer, the system must put the object on a queue of things needing immediate finalization (thus making it ineligible for reclamation) and unregister the finalizer.
Weak references and the references used for finalization are both invalidated automatically by the GC when all other references to an object are abandoned, and thus do not cause memory leaks. There's another kind of reference, however, which can cause nasty leaks: event subscriptions from publishers that outlive subscribers. If object A subscribes to an event from object B, object A cannot be garbage-collected unless either (1) it unsubscribes from the event, or (2) B itself becomes eligible for garbage-collection. I find myself puzzled at why Microsoft didn't include some means of automatic event unsubscription, but they didn't.

Categories