If broken it is, fix it you should

Using the powers of the debugger to solve the problems of the world - and a bag of chips    by Tess Ferrandez, ASP.NET Escalation Engineer (Microsoft)

.NET Garbage Collection PopQuiz

.NET Garbage Collection PopQuiz

Rate This
  • Comments 25

Time for a little pop-quiz/potential interview questions to get some action going in the comments section... 

Feel free to answer any or all of the below questions, I'll follow up with a post later if all of them are not answered...

 

1. How many GC threads do we have in a .NET process running the Server version of the GC on a dual-core machine?

2. What GC mode is used in the web development server (cassini) on a quad proc machine? Why?  (you can choose from server, workstation or concurrent-workstation)

3. How many finalizer threads do we have in a .NET process running the Server version of the GC on a quad proc machine?

4. When is an object garbage collected?

5. What causes an object to move from Generation 0 to Generation 1 or to Generation 2?

6. If you look at the GC sizes for Generation 0, 1 and 2 in perfmon, why is most of the memory in the process in Gen 2?

7. How many heaps will you have at startup on a 4 proc machine running the server GC?  How many would you have if the same machine was running the workstation GC?  Will the memory used for these show up in private bytes or virtual bytes in perfmon or both?

8. (Leading question:))  Is the fact that you have mscorwks.dll loaded in the process in 2.0 an indication of that you are running the workstation version of the GC?

9. Can you manually switch GC modes for a process?  If so, how and under what circumstances?

10. Name at least 2 ways to make objects survive GC collections unneccessarily.

11. Can a .NET application have a *real* memory leak?  In the C++ sense where we allocate a chunk of memory and throw away the handle/pointer to it?

12. Why is it important to close database connections and dispose of objects? Doesn't the GC take care of that for me?  

 

and if you don't think these questions are enough... feel free to post some of your own questions on the same theme...

Have fun,

Tess





  • 1. 2, 1 per processor

    2.  workstation

    3.  4

    4. When it is no longer rooted, and does not have a finalizer, or its finalizer has run and it has not been resurrected.

    5.  A GC occurs and the object is still rooted, on the finalization queue, or referenced by objects on the finalization queue. All such objects get promoted, either from Gen0->1, or Gen1->2.

    6. Probably because the objects in Gen0 and 1 get collected quickly and go away. Objects in gen 2 are collected infrequently, and objects tend to accumulate here in long running processes.

    7. 4, 1 per processor/GC thread, shows up in private bytes

    8. no. All versions are in same dll.

    9.  yes,but not while running, only before the runtime starts

    concurrent

    <configuration>

     <runtime>

       <gcConcurrent enabled="true" />

     </runtime>

    </configuration

    to run as server

    <configuration>

     <runtime>

       <gcServer enabled="true" />

     </runtime>

    </configuration>

    10.  

    1) If a object has a finalizer and GC.SupressFinalize is not called before the object is no longer rooted and a GC occurs. This could occur is the object is Disposed and GC.SupressFinalize is not called.

    2) If the object is no longer used but is referenced by an object that is still rooted. An example is where a form subscribes to an event (i.e. a multicast delegate) when it is opened and never unsubscribes from that event when it is closed.

    11. *real* memory leak?  

    Yes. Same example as a form that subscribes to an event and never unsubscribes. If the form is repeatedly opened and closed, then each instance will remain in memory even though it is no longer referenced anywhere (other then the delegate).

    12.  Those are essentially connections to unmanaged objects and are not automatically cleaned up. The GC cleans up memory, but that is all. Connections, (database, network, etc.) are not automatically deallocated.

    In some cases it is important to have precise lifetime control; files, network and database connections, etc., have this attribute.

    In addition, some objects have Close semantics (e.g. complex shutdown sequences), which are more involved then simply cleaning up its memory, and which require access to objects that may not be valid in the context of a finalizer. Usually you should not touch another managed object in a finalizer, but you can in a dispose method.

  • 1) 2 or 4 it hyper-threaded

    2) Don't know

    3) 4

    4) when it is not rooted AND there is a memory pressure

    5) when it is still rooted during GC 0, 1, etc

    6) Besides LOB, gc2 is not as frequently collected as GC 0 & 1. Also GC 2 is free but never compacted

    7) 4

    8) no true. it is true for 1.1

    9) in the config

    10) Finalizer and being referenced by root object

    11) Yes. Your example of ASP.NET Case Study: Tracing your way to Out Of Memory Exceptions.

    12) Because connection is a limited resource and GC does NOT know anything about connection. GC just knows raw data

  • 1. How many GC threads do we have in a .NET process running the Server version of the GC on a dual-core machine?

    I suspected the answer was 2 (one per logical processor) under the server GC.  Since you were kind enough to teach us to fish, I went ahead and ran windbg on a server with two dual-core processors, I ran a C# 2.0 console app that simply does a Console.ReadLine (with a gcServer enabled="true" specified in the app config file) and attached to it.  Using the ~k command to inspect the callstack for each native thread, I found 4 thread stacks starting with mscorwks!SVR::gc_heap::gc_thread_stub (the !SVR confirmed I was running in server gc mode...before adding the gcServer element to my app

    config, there was only one gc thread and its stack started with mscorwks!WKS, hence workstation gc mode).  So dividing the outcome by 2 (since again I had 2 dual-core

    processors), I confirmed my suspicion.

    2. What GC mode is used in the web development server (cassini) on a quad proc machine? Why?

    Probably workstation since it's a Windows Forms app.

    3. How many finalizer threads do we have in a .NET process running the Server version of the GC on a quad proc machine?

    Just one.  The ability to support multiple finalizer threads has been on the future enhancements list for some time now.

    4. When is an object garbage collected?

    When 1) a memory allocation request exceeds the current generation 0 segment capacity (or because of an exlicit call to GC.Collect) and 2) the object is no longer reachable.

    5. What causes an object to move from Generation 0 to Generation 1 or to Generation 2? Each time an object survives a collection, it is promoted to the next generation (unless it is pinned).

    6. If you look at the GC sizes for Generation 0, 1 and 2 in perfmon, why is most of the memory in the process in Gen 2?

    Gen 2 objects are those that have survived the longest.  Objects in the earlier generations are shorter-lived and quickly move to Gen 2 if they survive only 2 collections (which can come fast-and-furious depending on the amount of allocation going on).  Perfmon also doesn't typically update itself as fast as collections are going on, so you're seeing essentially a snapshot of "in-flight" objects making their way to Gen 2 or dying trying.

    7. How many heaps will you have at startup on a 4 proc machine running the server GC?  How many would you have if the same machine was running the workstation GC?  Will the memory used for these show up in private bytes or virtual bytes in perfmon or both?

    Assuming you are just talking GC Heaps (and not internal runtime heaps like the loader heap) the answer is 4 for server GC and 1 for workstation.  This is easily determined with the !EEHeap command in windbg with SOS.  Using the !ProcInfo command, it appears as though the memory shows up in both the Private and Virtual bytes.

    8. (Leading question:))  Is the fact that you have mscorwks.dll loaded in the process in 2.0 an indication of that you are running the workstation version of the GC?

    No.  Since 2.0, both flavors of the GC are implemented in mscorwks.dll (you can look for the !SVR and !WKS to tell the difference as described above).

    9. Can you manually switch GC modes for a process?  If so, how and under what circumstances?

    I doubt it, but if it can be done it would almost certainly have to be in a hosting scenario.

    10. Name at least 2 ways to make objects survive GC collections unneccessarily.

    Pin them or implement a finalizer (the latter of which always makes objects survive at least one extra generation as they are placed on the finalizer queue and possibly more if they are resurrected).

    11. Can a .NET application have a *real* memory leak?  In the C++ sense where we allocate a chunk of memory and throw away the handle/pointer to it?

    Sure.  It can easily happen during an Interop scenario.  Some scenarios also smell a lot like leaks such as compiled regular expressions and temporary assemblies created when emitting code (before lightweight codegen existed).

    12. Why is it important to close database connections and dispose of objects? Doesn't the GC take care of that for me?

    The GC only takes care of the managed portion of the memory.  It doesn't directly collect native memory or free their resources (although the kernel can reclaim most resources at process exit).

    -Brian Hartung

  • That are my 2 cents.

    7.- well, discarding low frequency heap and all that internall stuff, 8 heaps, 4 for normal heaps and 4 for LOH

    In a workstation, 2 heaps, the normal and the LOH

    In both counters because one of them is the reserved and the other, the commited memory

    8.- Nope. 2.0 has all the code in that dll.

    9.- Yes, but I tried and didn't work..at least in iis 5.1.

    10.- have a finalizer (that's not tru if you call gc.supressfinalizeme) and pinned.

    11.- No. At least in a 100% managed world, no.

    12.- It will take care, but could be too late for your server.

    Patrick.

  • Tess proposait il y a quelque temps, un Quiz sur le garbage collector http://blogs.msdn.com/tess/archive/2007/04/02/net-garbage-collection-popquiz.aspx

  • You've been kicked (a good thing) - Trackback from DotNetKicks.com

  • It was really exciting to see that so many people answered the .NET GC PopQuiz , especially seeing that

  • Als Nachtrag zu meinem gestrigen Post In den Tiefen des .NET Frameworks – Der Garbage Collector heute

  • wat is the size of the managed heap allocated by a preocess at runtime?

  • I recently was asked to take a look at some VSTO test automation that wasn't behaving correctly on lab

Page 2 of 2 (25 items) 12
Leave a Comment
  • Please add 2 and 8 and type the answer here:
  • Post