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

When garbage collection occurs, does it halt all app domains in a given process during the collection, or just a single app domain? Is this irrespective of all garbage collection parameters?

If one wants to separate two logical modules of code from trigger garbage collections on each other, is the only way to isolate them in two separate processes?

Thanks in advance, and please provide a reference source for your answer.
LVL 2
ebyrneAsked:
Who is Participating?
 
MogalManicConnect With a Mentor Commented:
The three numbers in parentheses are the Garbage collection counts for each Generation (0, 1, 2).  You can see that each application domain has done the same # of garbage collections (even though I modified the code to do the garbage collections randomly)
0
 
MogalManicCommented:
Garbage collection happens on a separate thread.  When it occurs it will freeze all threads in the application domain.  Here are two articles that fully describe the GC process:
  http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
  http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

Here is reference GC pages:
  http://msdn.microsoft.com/en-us/library/0xy59wtx(VS.80).aspx

I don't think there is any way to STOP garbage collection, but there are ways you can force a collection to limit its effects on critical sections:
  http://www.dotnetuncle.com/Framework/50_gc_activities.aspx
  or using code like this:
        ......
        GC.Collect();
        GC.WaitforPendingFinalizers();
        for (int i=0; i<1000; i++)
        {
                somelist.Add(new someobject());
        }
        ......
0
 
ebyrneAuthor Commented:
Hi Mogul,

Thanks for the response. So you state that "when [GC] occurs it will freeze all threads in the application domain". Do you have any reference point for that? That's the primary point I'm after, whether that occurs on the AppDomain or process level, and I didn't find an answer in those articles. I've seen some references (mainly boards) saying it happens on the process level, but haven't found a source I could trust yet (and it's kinda hard to test definitively for..).

Anyone have such a reference?


[As a side note, the last recommendation there is very dangerous. Not only are you forcing a GC, but you've only made a GC less likely by attempting to preempt your allocations. If someone else really needs to go such a road (and you prob shouldn't), you're gonna want to explore your options. For instance, take a look at: http://blogs.msdn.com/bclteam/archive/2005/06/14/429181.aspx or on the various GC Modes, http://blogs.msdn.com/clyon/archive/2007/03/12/new-in-orcas-part-3-gc-latency-modes.aspx. Post if you need more guidance..]
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

 
MogalManicCommented:
The reference is in the 2nd article in the heading titled:Performance for Multithreaded Applications

So, when the garbage collector wants to start a collection, all threads executing managed code must be suspended. The runtime has a     few different mechanisms that it uses to safely suspend threads so that a collection may be done. The reason there are multiple mechanisms is to keep threads running as long as possible and to reduce overhead as much as possible. I don't want to go into all the details here, but suffice it to say that Microsoft has done a lot of work to reduce the overhead involved with performing a collection. Microsoft will continue to modify these mechanisms over time to help ensure efficient garbage collections.



I agree with your second comment.  You probably should not muck with the GC class until you have exhausted all other code optimization tricks:
  -Using classes that optimize large allocations (i.e. StringBuilder instead of string+string)
  -Clearing out references to objects not being used anymore
  -Creating objects that implement the IDisposible interface when necessary
  -Using the "Using" clause for IDisposable objects
0
 
ebyrneAuthor Commented:
Hi Mogal,

I'm probably dense here, but I still don't see the answer. I agree with the first statement that all threads are suspend. Where does it indicate whether that refers to all threads in the current process or all threads in the current AppDomain?

Thanks again.
0
 
MogalManicCommented:
I found another thread that had some sample code.

http://stackoverflow.com/questions/241537/what-is-the-scope-of-finalizer-thread-per-application-domain-or-per-process

I modified the code to make it more random and took out the GC.WaitForPendingFinalizers()
and got this Result:
using System;
 
class Test
{
    static void Main()
    {
        AppDomain.CreateDomain("First")
                 .ExecuteAssembly("ShowFinalizerThread.exe");
        AppDomain.CreateDomain("Second")
                 .ExecuteAssembly("ShowFinalizerThread.exe");
    }
}
 
//In another project
using System;
using System.Threading;
 
class ShowFinalizerThread
{
    static Random rng = new Random();
    string RandomString;
    ShowFinalizerThread()
    {
        RandomString = BuildRandomString();
    }
    ~ShowFinalizerThread()
    {
        Console.WriteLine("Thread/domain: {0}/{1}:({2},{3},{4})",
                          Thread.CurrentThread.ManagedThreadId,
                          AppDomain.CurrentDomain.FriendlyName,
                          GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2));
        
        if (rng.Next(10) == 0)
        {
            Console.WriteLine("Hanging!");
            Thread.Sleep(rng.Next(2000));
        }
    }
 
    private string BuildRandomString()
    {
        string RandomString = "This is Random Padded".PadRight(rng.Next(1000), 'X');
        return RandomString;
    }
 
    static void Main()
    {
        new Thread(LoopForever).Start();
    }
 
    static void LoopForever()
    {
        while (true)
        {
            new ShowFinalizerThread();
            if (rng.Next(1000) == 0)
            {
                GC.Collect();
            }
            Thread.Sleep(0);
        };
    }
}

Open in new window

AppDomainTest.png
0
 
ebyrneAuthor Commented:
Process it is.

You know, it's embarrassing, but I didn't even think to look at the collection count, that makes perfect sense of course. That's for taking the time to code it up and test it out Mogal, much appreciated!

Thanks again!
0
 
ebyrneAuthor Commented:
Much thanks Mogal, I appreciate all the effort. Beyond and above for sure.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.