How I can free an assembly after loading it using reflection? - c#

I noticed in testing, that multiple calls to the following code creates a memory leak :
object obj = Activator.CreateInstance(Type.GetType(arg2.DeclaringType.FullName));
arg2.Invoke(obj, new object[] { arg3 });
For the above code, arg2 is MethodInfo type ; arg3 is string[]
Even if I add obj = null; after the Invoke, it seems that GAC doesn't collect this object for cleanup. (yes, I know setting an object to null is a poor excuse for dispose(), however as this is a generic method, there may or may not be a dispose() available in the class, and tested with assemblies that do have dispose, they are not unloaded after use)
I have consider using a cache mechanism where the loaded assembly is stored in a dictionary for subsequent lookups, however there is no guarantee that GAC won't come and clean it up later making that object in dictionary unusable (among other disasters).
How can I force an unload of the class (similar to the way I can force it to load by calling Activate) once I am finished with it ?

Let's get this straight, you can not unload an assembly when it has been loaded unless you unload the entire Application Domain.
(and if you want to know why : check this blog)
However, with a class it is different, you are talking about releasing it from memory. First of all, are you sure that no other object have an access to it ?
When you are sure of that, know that the Garbage Collector will release the memory of the unreferenced objects whenever it wants to, so talking about memory leak might be a bit prematured...
You can however force the Garbage Collector to clean up the memory by calling GC.Collect()

Related

Releasing Com Objects Doesnt Affect Memory Usage

When I release com objects by Marshall.ReleaseComObject method, memory usage of application doesnt change. Instead of using Marshall.ReleaseComObject, using Garbage Collector (GC.Collect()) can release memory area of com objects but the UI is getting slow down.
So my question is, what is the best method to release com objects?
Athough a bit outdated (as from ArcGIS 10.0) the rules for releasing and how to do so are pretty well described on http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#/Releasing_COM_references/0001000004tm000000/.
There are two ways to do this. Either by using Marshal.ReleaseCOMObject or by the ComReleaser-class which essentially is a wrapper around the former. However you may have multiple references to the exact same com-object, which is why calling ReleaseComObject will not finally release the object, but simply decrease the internal reference-counter by one. Only when that counter is equal to zero the object will actually be released. See here for example:
var f1 = featureClass.GetFeature(1);
// retrieve the exact same feature again
var f2 = featureClass.GetFeature(1);
Although from a .NET-perspective f1 and f2 are comlpletely different objects, the underlying com-object is the same (assuming unique-instancing, which is out of the scope of this question). When calling Marshal.ReleaseComObject on either f1 or f2, you will only decrease the internal reference-counter for this com-object by one, leaving one reference alive.
GC.Collect however has no effect as it can´t handle unmanaged resources which com-objects are. The garbage-collector is only able to release managed resources. Calling GC.Collect will thus only - if at all - release the runtime-callable-wrapper, which is a managed wrapper around the unmanaged object. The latter however still exists in memory and is likely to produce a dead-leak.
Having said this the only way to finally release a com-objects is to call Marshal.ReleaseComObject in a loop until the reference-counter is zero.
while(Marshal.ReleaseComObject(myObject) > 0);
Afterwards you may or may not call GC.Collect. However I won´t suggest to do so, as the garbage-collector knows best when to release a mananed object. Forcing it to do so will at best work as expected, at worst however only mke your code slow without having any positive effect. GC is un-determinsitc process, you can´t really influence it.
Best way to do is using ComReleaser or Marshal.ReleaseComObject methods. Calling GC.Collect method too much will cause to slow down of your application. Let GC do its job when needed.
Try this,
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oApp);
oApp = null; // Set each COM Object to null
//
// After all of the COM objects have been released and set to null, do the following:
GC.Collect(); // Start .NET CLR Garbage Collection
GC.WaitForPendingFinalizers(); // Wait for Garbage Collection to finish
If object implement finalizer, call gc means put this object reference in finalization queue, means it doesnt release immediately.

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.

Are static class members pinned?

I have a C# class, having a static ImageList object. This image list will be shared with various ListView headers (via SendMessage... HDM_SETIMAGELIST) on several forms in my application.
Though I understand that static objects are not eligible for garbage collection, it is not clear to me if they are also ineligible for relocation (compaction) by the garbage collector. Do I also need to pin this object since it is shared with unmanaged code, say, using GCHandle.Alloc?
Environment is VS 2008, Compact Framework 3.5.
The instance itself is not static. The reference is. If you null the reference the instance becomes eligible for GC. Internally, all static instances are references through a pinned handle to an array of statics. I.e. the instance is implicitly pinned by the runtime.
If you look at the GCroot of an instance declared as a static member, you'll see something like this:
HandleTable:
008113ec (pinned handle)
-> 032434c8 System.Object[]
-> 022427b0 System.Collections.Generic.List`1[[System.String, mscorlib]]
If you null the static reference the corresponding entry in the pinned array is nulled as well.
Now, these are obviously implementation details so they could potentially change.
Yes. You need to pin the object.
While it's true that the reference is static, that is, you may access this location anywhere from your member it's reference is still a GC handle. That is, it's eligible for garbage collection (and/or compaction) but it will of course never happen.
I don't think it's necessarily wrong to think that the static modifier implies that it will eventually have a static location in memory but there bigger issue is that there's no API that allows you to get at the memory address without pinning the object. Whether it's being moved by the GC or not.
Moreover, each static member is unqiue per AppDomain (not process). The same static member could exist in different memory locations in the same process and it can be garbage collected when the AppDomain unloads. This is quite the edge case I'll admit but there's no real advantage of not pinning objects even if it could be done without pinning.
Do I also need to pin this object since it is shared with unmanaged
code, say, using GCHandle.Alloc?
Yes. If the pointer is not pinned, GC is free to move that memory, so you may have dangling C++ pointers, pointing to some non valid, or worse, non their memory at all.
Also, "shared" word should be clarified. If you allocate and pass to unmanaged memory, which copies it somewhere, you may avoid to pin them constantly. Depends on what happens once you pass control to unmanaged environment.
EDIT
Even considering interesting answer from #Brian, I would still opt for pinning the pointer. To make explicit in the code the notion of the fixed pointer, avoid any possible misguide in future code maintenance and keep clarity.

Memory management while Loading assembly using reflection

All,
I am creating a component that uses composite pattern. The core component uses an XMl Meta data to define the composites (parts). at run time, the core component would use reflection to load the part assembly into the memory and call methods (e.g IPart.execute method).
Now my question is
1) will the (dynamic) memory that is occupied by the assembly that is loaded using reflection will be unloaded when i dispose the object or not.
2) if it does not unload and free the memory, is there is any way i can remove it from memory.
The reason of this question is, the component which i am building will be the core of my Business layer of an enterprise application which can be customized heavily.
Thanks
Albert Arul Prakash
I've seen people load additional libraries via reflection (we could call these libraries "plugins") in another appdomain. For instance, see this article: http://adrianvintu.com/blogengine/post/Unloadable-plugins.aspx
This way you are protected from "evil" plugins as well as memory can be managed in such appdomain (when the appdomain unloads, the memory is freed up as well)
There are two things that can consume memory in a plugin/module. Grossly speaking, these are code (loading the assembly into your process space consumes memory), and objects (creating an instance of something consumes memory).
will the (dynamic) memory that is occupied by the assembly that is loaded using reflection will be unloaded when i dispose the object or not.
Calling Dispose on IDisposable doesn't do anything to the object as far as memory is concerned. It might free resources that the object uses (e.g. if you close a file, it will get rid of open file handles), but it won't free the object itself. IDisposable isn't a magic memory-freeing function - it is just a method on an interface that lets an object know that it should get rid of resources that it owns.
To free the object itself, you must get rid of all references to it (possibly set them to null, or let them fall off your program's stack), and the garbage collector must eventually run to reclaim that memory.
if it does not unload and free the memory, is there is any way i can remove it from memory.
If you are only concerned about resources like GUI and file handles, make sure you call Dispose. You should always do this :)
If you are concerned about object memory, just let the GC do its work. Don't pester it to, either. Let it run on its own.
If you are concerned about code memory, you must unload the AppDomain that the code is in. If this is your default AppDomain then you can't unload it without quitting your program. Instead, you should load that plugin in a sub AppDomain that you created at runtime. You can then get the code out of your process space by unloading the sub AppDomain.
See naivists' answer for information on how to use a sub AppDomain.

How to force garbage collection of object you can't dereference?

We are using EWS Managed API which polls MS Exchange for new mail messages after a given interval. With each invocation of the polling call (PullSubscription.GetEvents()) - Microsofts API is failing to properly dispose the NetworkStream and causes memory to proportionately increase. This was previously discussed here, but never resolved. Using ANTS Profiler we were able to determine which objects were continuously growing in memory and isolate the issue.
Now that the issue has been isolated - is there a way to dispose of a NetworkStream created in an external API that we don't have a reference to? GC.Collect() doesn't seem to dispose it since it still has an active reference. What can we do to cleanup the dangling reference? Is there some wrapper we can use to force cleanup of their buggy SDK?
There is no way to force GC to release memory for a referenced object!
First of all I would suggest to contact microsoft itself for help with this bug.
Second, are you talking about "disposal" or just memory release? They are two totally different things. (IDisposable pattern, finalizers).
Third, can u just dereference the object that are referencing these objects?
Fourth, one possible solution can be to decompile with reflector the code that is giving you the issue, understand a way you can arrive to the fields that are keeping the referenced objects, use reflection in your code to access the private fields and put them to null.
Is a very dirty hack, but if you have no other way is the only thing i can think of. Do this only if you cannot go in any other ways.
The most easy way would be running the part the is interfacing the SDK into its own AppDomain and after your are done unload the AppDomain. This will cause all the memory allocated in the AppDomain to be freed.
But you will need add some work to your project since you can only interchange with an AppDomain the a MarshalByRef object or marked as serilizable.
This will also allow you to monitor the amount of memory consumed by the AppDomain. So you can create your AppDomain, run the buggy SDK in it and if it reaches a special limit of memory consumption you can unload it.

Categories