AppDomain creation gets increasingly expensive

C

Chris Lacey

Hi,

I'm currently writing a scheduling service which starts a number DotNet
executables, each within a new AppDomain, every ten seconds.

The guts of the code is as follows:

// For each executable in the list of tasks
for (int i = 0; i < this.processTasks.Length; i++)
{
try
{
// Create a suitable name for the AppDomain
string[] taskArgs = this.processTasks.Trim().Split(' ');
string appDomainName = String.Format("Task {0}", i);

// Create a new AppDomain for the task
Trace.WriteLine(String.Format("Creating AppDomain '{0}'",
appDomainName));
AppDomain appDomain = AppDomain.CreateDomain(appDomainName);

try
{
// Execute the assembly in the AppDomain
Trace.WriteLine(String.Format("Executing assembly '{0}' on AppDomain
'{1}'", taskArgs[0], appDomain.FriendlyName));
appDomain.ExecuteAssembly(taskArgs[0],
AppDomain.CurrentDomain.Evidence, taskArgs);
}
catch (Exception e)
{
// Log any errors
Trace.WriteLine(e.ToString(), EVENT_SOURCE);
EventLog.WriteEntry(EVENT_SOURCE, e.ToString(),
EventLogEntryType.Error);
}
finally
{
// Unload the AppDomain
Trace.WriteLine(String.Format("Unloading AppDomain '{0}'",
appDomain.FriendlyName));
AppDomain.Unload(appDomain);
}
}
catch (Exception e)
{
// Log any errors that may be thrown in the finally block above

At the moment, because I have six executables in the processTasks array, 6
new AppDomains are created and destroyed on every pass.

As time has gone on (the schedule process has been running for several
days), the time taken to create/destroy an AppDomain has gone from 1s to
about 12s, and the memory usage of the process has crept steadily upwards.

Should I be creating and destroying AppDomains with this rapidity, or are
they simply not designed for this use? Or am I not getting rid of them
properly with the simple AppDomain.Unload().

Any info very greatefully received!!

Many thanks,

Chris.
 
G

Guest

If you are starting the same apps every 10 seconds, consider making them
services that run their business every 10 seconds instead. This will be much
less overhead on the system.

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

***************************
Think Outside the Box!
***************************
 
C

Chris Lacey

Thanks, Gregory.

The single service that schedules all of the other applications is required
because the list of executables is determined by the end user (in a
configuration file). We also need to be sure that these run sequentially,
and not in parallel.

AppDomains seem like the right thing to use here - and I can cope with a
small (consistent!) delay in creating and destroying them - but the
increasing memory usage and creation time seems to imply they are not
"fully" destroyed.

Any ideas?

Thanks in advance,

Chris.
 
W

Willy Denoyette [MVP]

Chris Lacey said:
Thanks, Gregory.

The single service that schedules all of the other applications is
required because the list of executables is determined by the end user (in
a configuration file). We also need to be sure that these run
sequentially, and not in parallel.

AppDomains seem like the right thing to use here - and I can cope with a
small (consistent!) delay in creating and destroying them - but the
increasing memory usage and creation time seems to imply they are not
"fully" destroyed.

Any ideas?

Thanks in advance,

Chris.


If I get you right you load six AD, every 10 seconds, that makes 24 * 60 *
36 = 51840 AD/Day, this is quite a lot if you consider the possibility that
some types might leak through the AD boundaries and as such wont be unloaded
when the secondary AD unloads.
I'm also not clear on why you load an .exe assembly in an application
domain, why not simply start the .exe as a separate process? If this is not
possible (which I doubt), I would suggest you to recycle the process every
now and then, say once a day.


Willy.
 
J

Jon Shemitz

Chris said:
The guts of the code is as follows:
AppDomain appDomain = AppDomain.CreateDomain(appDomainName);
appDomain.ExecuteAssembly(taskArgs[0],
AppDomain.CurrentDomain.Evidence, taskArgs);
AppDomain.Unload(appDomain);

As time has gone on (the schedule process has been running for several
days), the time taken to create/destroy an AppDomain has gone from 1s to
about 12s, and the memory usage of the process has crept steadily upwards.

Should I be creating and destroying AppDomains with this rapidity, or are
they simply not designed for this use? Or am I not getting rid of them
properly with the simple AppDomain.Unload().

The guts look fine, and Unload IS what you should be doing. My guess
is that you stripped something seemingly innocuous, and that's what's
causing these increasing create/destroy times.

One trick I have found very useful for debugging app domains is to
watch the assemblies loaded into the default appdomain -
AppDomain.CurrentDomain.GetAssemblies(). Buggy app domain code often
'leaks' assemblies into the main domain.
 

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

Top