sa.he
sa.he

Reputation: 1421

Does garbage collection happen at the process level or appdomain level?

FullGC normaly pauses all Threads while running. Having two AppDomains, each running several threads. When GC runs, will all threads be paused, or only those of either one AppDomain?

Upvotes: 30

Views: 3743

Answers (2)

jordanhill123
jordanhill123

Reputation: 4182

From this thread here: Is the garbage collector in .net system-wide or application-wide?, it occurs on the process level. All threads in that process will be paused but not across multiple processes.

One or multiple app domains can exist within a process but app domains are not shared between processes. Per: http://blogs.msdn.com/b/tess/archive/2008/08/19/questions-on-application-domains-application-pools-and-unhandled-exceptions.aspx,

"all appdomains in the process share the same GC."

Accordingly, GC should affect all app domains when a GC is triggered.

However, a CPU performance hit can occur with too many processes spending time doing GC which can negatively affect the performance of other processes not involved in a GC.

This link also explains the fundamentals of GC too:

http://msdn.microsoft.com/en-us/library/ee787088.aspx

Upvotes: 14

Hans Passant
Hans Passant

Reputation: 941495

Hard to answer, best thing to do is just test it:

using System;
using System.Reflection;

public class Program : MarshalByRefObject {
    static void Main(string[] args) {
        var dummy1 = new object();
        var dom = AppDomain.CreateDomain("test");
        var obj = (Program)dom.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Program).FullName);
        obj.Test();
        Console.WriteLine("Primary appdomain, collection count = {0}, gen = {1}",
            GC.CollectionCount(0), GC.GetGeneration(dummy1));
        Console.ReadKey();

    }
    public void Test() {
        var dummy2 = new object();
        for (int test = 0; test < 3; ++test) {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        } 
        Console.WriteLine("In appdomain '{0}', collection count = {1}, gen = {2}",
            AppDomain.CurrentDomain.FriendlyName, GC.CollectionCount(0),
            GC.GetGeneration(dummy2));
    }
}

Output:

In appdomain 'test', collection count = 3, gen = 2
Primary appdomain, collection count = 3, gen = 2

Good evidence that a GC affects all AppDomains on the default CLR host. This surprised me.

Upvotes: 17

Related Questions