how to unload assembly and free the memory?

  • Thread starter Thread starter navyliu
  • Start date Start date
N

navyliu

please help me,I've searched for the solution for two days,but i can't find
the perfect solution.
 
I think you are talking about dynamically loading a assembly..

Bellow is a method I used to load set of assembly which has it's entry class
derived from an iterface named ITciSchedulerJob, with a little treak you may
use it in your code

using System.Reflection;

private ITciSchedulerJob GetCurrentJobWorker(string path, string
name)
{
try
{
this.LogInfo("Assembly is about to load from Path: " +
path);
Assembly ass = Assembly.LoadFrom(path);
this.LogInfo("Assembly is loaded Full Name: " +
ass.FullName);
this.LogInfo("Assembly is about to cast to correct type Name
: " + name);
ITciSchedulerJob job =
(ITciSchedulerJob)ass.CreateInstance(name);
if (job == null)
throw new System.Exception("Null object retrieved after
creating the instance");
return job;
}
catch (System.IO.FileNotFoundException e)
{
throw new DllNotFoundException(e.Message);
}
catch (System.IO.FileLoadException e)
{
throw new DllNotFoundException(e.Message);
}
catch (System.Security.SecurityException e)
{
throw new DllNotFoundException(e.Message);
}
catch (System.ArgumentNullException e)
{
throw new DllNotFoundException(e.Message);
}
catch (System.ArgumentException e)
{
throw new DllNotFoundException(e.Message);
}
catch (System.BadImageFormatException e)
{
throw new DllNotFoundException(e.Message);
}
catch (System.MissingMethodException e)
{
throw new DllNotFoundException(e.Message);
}
}

Nirosh.
 
Again, Unloading can be done just by making the loaded assmebly a
unreachable object.. i.e. assign it to null

Nirosh.
 
hi Champika Nirosh£¬thank you for you reply.
Yes I'm talking about dynamically loading an assembly. I know how to load an
assembly,but I can't find the way to unload an assembly and free the memory
it held.
I have searched this topic in google with Assembly.Unload and found a lot.
But it seems there's no right solution to solve
the problem.
Here are some links:
Jason Zander's WebLog : Why isn't there an Assembly.Unload method?
http://blogs.msdn.com/jasonz/archive/2004/05/31/145105.aspx

I tried to load an assembly in a separated AppDomain and Call
AppDomain.Unload() after using the assembly, but the memory is not freed.
 
hi Champika Nirosh£¬thank you for you reply.
Yes I'm talking about dynamically loading an assembly. I know how to load an
assembly,but I can't find the way to unload an assembly and free the memory
it held.
I have searched this topic in google with Assembly.Unload and found a lot.
But it seems there's no right solution to solve
the problem.
Here are some links:
Jason Zander's WebLog : Why isn't there an Assembly.Unload method?
http://blogs.msdn.com/jasonz/archive/2004/05/31/145105.aspx

I tried to load an assembly in a separated AppDomain and Call
AppDomain.Unload() after using the assembly, but the memory is not freed.
 
| hi Champika Nirosh£¬thank you for you reply.
| Yes I'm talking about dynamically loading an assembly. I know how to load
an
| assembly,but I can't find the way to unload an assembly and free the
memory
| it held.
| I have searched this topic in google with Assembly.Unload and found a lot.
| But it seems there's no right solution to solve
| the problem.
| Here are some links:
| Jason Zander's WebLog : Why isn't there an Assembly.Unload method?
| http://blogs.msdn.com/jasonz/archive/2004/05/31/145105.aspx
|
| I tried to load an assembly in a separated AppDomain and Call
| AppDomain.Unload() after using the assembly, but the memory is not freed.
|
|

What do you mean with "the memory is not freed". You are expecting an unload
of the assembly, is the assembly unloaded after the Domain.Unload or not? If
the assembly is unloaded, your mission is accomplished, if not you have a
problem.

Willy.
 
Yes,I did,but it doesn't work.
hi Nirosh,My MSN is (e-mail address removed)
 
Hi Willy,thank you for you reply.
My test workes following:
1. Create a new AppDomain;
2. Load an Assembly with the method AppDomain.Load;
3. Create an Instance of a Control and use it.
4. Remove the Control and set the Instance null;
5. UnLoad the AppDomain.

but the memory is not freed.
I'm designing an Plugable Framework. The plug-ins can be very large.
If i don't free the memory the Assembly held, the memory will soon be
used up.
 
| Hi Willy,thank you for you reply.
| My test workes following:
| 1. Create a new AppDomain;
| 2. Load an Assembly with the method AppDomain.Load;
| 3. Create an Instance of a Control and use it.
| 4. Remove the Control and set the Instance null;
| 5. UnLoad the AppDomain.
|
| but the memory is not freed.
| I'm designing an Plugable Framework. The plug-ins can be very large.
| If i don't free the memory the Assembly held, the memory will soon be
| used up.
|
|
You should verify whether the assembly did unload with the application
domain. If the assembly unloads, you should not care about the memory, this
will be taken care of by the CLR.


Willy.
 
navyliu said:
But it seems there's no right solution to solve
the problem.

You need to load the assembly into a seperate AppDomain, as .NET managed
DLLs are only unloaded if the hosting AppDomain is unloaded.

Best regards,
Martin
 
There isn't an UnLoad Method in Assembly Class.How can I verify whether the
assebly
did unload?
 
| There isn't an UnLoad Method in Assembly Class.How can I verify whether
the
| assebly
| did unload?
|


Use "Process.Modules" to see what assemblies are loaded into the process, if
you need to know the assemblies loaded into the current AD, you can use
AppDomain.CurrentDomain.GetAssemblies().

Willy.
 
Hi,

IIRC the only way to unload an assembly is if you loaded it in another
appDomain, if not ( as is your case) it will NEVER unload
 
Hi,

How are you determining the memory used?
It's possible that the memory used is not returned right away to the OS ,
especially if the OS has spare memory
 
Once loaded into a particular app domain an assembly cannot be unloaded.
You'd have to create a seperate app domain for each assembly (is this a
plugin thing perhaps) and then unload the app domains when they weren't
needed anymore.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
Make sure that you do not pass the reference to any objects creatd in the
new appdomain back to the default appdomain. This causes the assembly to get
loaded into both appdomains and you will not be able to unload it. This also
means that you can't do something like this...

AppDomain ad = new AppDomain(...);
ad.Load(asmName);

This causes the assembly identified by asmName to get loaded into both
appdomains, because the reference to the loaded assembly is passed across
the appdomain boundary back to the default appdomain.

This link describes most of what you need to know...

http://www.gotdotnet.com/team/clr/AppDomainFAQ.aspx
 
hi
I have read some articles,but I think they can't solve my problem.
The solution for unloading Assembly follows following steps:
1.Create a new AppDomain;
2.In the new AppDomain,Load some assembly;
3.Create an Instance of some Class and send the instance outside the
appdomain for using through Remoting.

the problem is step 3.
I want to use these Instances(usually are UserControls) in my plugable
framework. I have to pass object between AppDomains.
The only way to pass object between AppDomain is remoting.
That's to say all my plug - in must inhert MarshalByRefObject.
I have tested. The UserControl can pass to the framework,
but it can be add into the Container. the exception is following:
"Remoting can't find the field parent from Type
System.Windows.Forms.Control".
?????????"System.Windows.Forms.Control"?????"parent"?

If you want to discuss this problem directly,you can add my msn
:[email protected].
Best regards.
Navyliu
 
Unfortunately you cannot remote a UI component across appdomains - currently
only non-GUI objects can be remoted. It's not that you cannot create a
remoted UI object, you just can't use it to display anything. You can use it
for non-UI purposes (e.g. it exposes some business logic in addition to UI).

We've brought this up with MSFT and requested this feature and have not
gotten any responses about when, or if ever, this will be supported. For now
your plugins must only expose business logic through its remoted interface.
It can still do UI but that must all be within a single appdomain (not part
of a remoted interface).
 
Hi David.How did you avoid use the memory up while using plugin modal?
Can you give me some advise or some sample code?
Thank you very much.
Best regards
Navyliu.
 
navyliu said:
Hi David.How did you avoid use the memory up while using plugin modal?

If by this you are asking: how did I unload the assemblies...the answer is
given in the FAQ link I sent you.

The basic rule is to never directly call any method that returns a reference
from the default appdomain into another appdomain. Instead, create a remoted
object in the second appdomain and call to that from the default appdomain.
The remoted object must completely execute whatever functions you need to
perform. It can return status codes and shared types that are defined in
both appdomains (e.g. ints, strings, etc.) but it does not return any type
or reference to a type that is defined in an assembly that you want to
unload in the second appdomain.

In other words, if you have an assembly foo.dll that defines a type fooType,
do not return a reference to one fooType back to the default appdomain. You
also cannot return a reference to the loaded assembly foo.dll. Either of
these cause foo.dll to get loaded into both appdomains and you will not be
able to unload it again. You must use a proxy class that completely hides
the types used in the secondary appdomain from the default appdomain.

Can you give me some advise or some sample code?

I do not have a simple sample code set I can give you. However, there are
plenty of samples scattered around the internet - google up a plugin model
for .net. Athe FAQ also gives a good starting point.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top