Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this COM object subject to garbage collection?

I'm using a COM object from .NET using interop. The object basically fetch data from socket and fire some events for .NET layer to process. However, after a while, the COM object stops firing events which revealed later to be because it's collected by GC.

The structure of source code is similar to this one below:

static void Main(string[] args)
{
    MyEventGen gen = new MyEventGen();
    WeakReference wr = new WeakReference(gen);
    gen.ReceiveDataArray += 
            new _IMyEventGenEvents_ReceiveDataArrayEventHandler(gen_ReceiveDataArray);
    while (true)
    {
        Thread.Sleep(1000);
        Console.WriteLine(wr.IsAlive);
    }
}

static void gen_ReceiveDataArray(ref Array indices, ref Array values)
{
    // do nothing
}

alt text

What I know so far:

  • From what I understand, object gen shouldn't be garbage-collected in any way. Since the object is still active in the Main scope. But the result so far shows that the object was collected by GC.

  • The object is only garbage-collected when built as Release and run without debugging. Running the Debug builds / running both modes under debugger are fine.

  • The program will print the first "False" precisely after the first Gen #0 Collection.

  • By accessing the object in the while loop, e.g. Console.WriteLine(gen.ToString()) , prevent it from being GC'd!

  • By adding another static field of Program class to keep its reference also prevent it from GC'd.

  • Trying with different load of data, I found that GC only collects the object when Private Bytes reach over the threshold of ~ 3X MBs.

  • Checking with CLRProfiler, mentioned object was GC'd as suspected.

Have I missed some important .NET GC's concepts? Is it possible to obtain the reason for object being GC'd? Is this, possibly, a known GC bug?

I'm using VS 2008 + .NET 3.5 SP1. Appreciate your thoughts. Thanks!

like image 627
Gant Avatar asked Jan 21 '11 10:01

Gant


People also ask

How do you know if an object is eligible for garbage collection?

An object is eligible to be garbage collected if its reference variable is lost from the program during execution. Sometimes they are also called unreachable objects. What is reference of an object? The new operator dynamically allocates memory for an object and returns a reference to it.

Does Objective C have garbage collection?

Objective-C 2.0 adds garbage collection to the language as a replacement to the traditional retain / release reference counting scheme. Garbage collection is automatic object memory management.

What is the main object of garbage collection?

The main objective of Garbage Collection is to free heap memory by destroying the objects that don't contain a reference. When there are no references to an object, it is assumed to be dead and no longer needed. So the memory occupied by the object can be reclaimed.

What is the example of garbage collection?

The best example of garbage collector is Daemon thread that is always running in the background. So, the main objective of Garbage Collector in java is to free up heap memory by destroying unreachable objects that are not referenced by any reference variable.


2 Answers

No need to use a COM object to reproduce this. Consider the following:

public class MyEventGen
{
    public event Action ReceiveDataArray;
}

class Program
{
    public static void Main()
    {
        var gen = new MyEventGen();
        var wr = new WeakReference(gen);
        // this is the last time we access the 
        // gen instance in this scope so after this line it
        // is eligible for garbage collection
        gen.ReceiveDataArray += new Action(gen_ReceiveDataArray);

        // run the collector
        GC.Collect();
        while (true)
        {
            Thread.Sleep(1000);
            Console.WriteLine(wr.IsAlive);
        }
    }

    static void gen_ReceiveDataArray()
    {
    }
}

Run it in Release mode and it will exhibit the same behavior. The gen object falls out of scope and is garbage collected because there is nothing to keep it alive during the execution of the loop.

like image 178
Darin Dimitrov Avatar answered Nov 14 '22 23:11

Darin Dimitrov


Neither gen nor wr remain active in the Main scope during the execution of your while loop. You enclosed the first three lines in braces which puts those variables in a child scope that is exited before your while loop begins.

like image 26
Martin Avatar answered Nov 15 '22 00:11

Martin