Question

Or is it already to late if the finalize method is reached?

Basically I'm creating some code to log to a MySql database. Each log entry is represented by an object and stored in a queue until it gets flushed to the database in a batch insert / update. I figured it'd be inefficient to create a new object on the heap every time I wanted to write an entry (especially since I might want to write an entry or two in performance sensitive areas). My solution was to create a pool of objects and reuse them.

Basically I'm trying to not re-invent the wheel by letting the .Net Garbage Collector let me know when an object is no longer needed and can be added back to the pool. The problem is I need away to abort garbage collection from the destructor. Is that possible?

Was it helpful?

Solution 2

Connection pooling is a feature virtually any major DB connection implementation is already going to natively support, so there is no reason to handle this manually. You'll be able to simply create a new connection for each operation and know that behind the scenes the connections will actually be pooled.

To answer the literal question that you asked, yes. You can ensure that an object is not going to be GCed after it is finalized. You can do so simply by creating a reference to it from some "live" location.

This is a really bad idea though. Take a look at this example:

public class Foo
{
    public string Data;
    public  static Foo instance = null;
    ~Foo()
    {
        Console.WriteLine("Finalized");
        instance = this;
    }
}

public static void Bar()
{
    new Foo() { Data = "Hello World" };
}

static void Main(string[] args)
{
    Bar();
    GC.Collect();
    GC.WaitForPendingFinalizers();
    Console.WriteLine(Foo.instance.Data);
    Foo.instance = null;

    GC.Collect();
    GC.WaitForPendingFinalizers();
}

This will print out:

Finalized

Hello World

So here we had an object end up being finalized, and we then accessed it later on. The problem however is that this object has been marked as "finalized". When it is finally hit by the GC again it's not finalized a second time.

OTHER TIPS

Can you? Yes.
Should you? No, it is almost certainly a terrible idea.

The general rule C# developers should remember is the following:

If you find yourself writing a finalizer, you probably did something wrong.

The memory allocators used by well-established managed VMs (such as the CLR or JVM) are extremely fast. One of the things that slows down the garbage collector in these systems is the use of customized finalizers. In an effort to optimize the runtime, you are actually giving up a very fast operation in favor of a much slower operation. Furthermore, the semantics of "bringing an object back to life" are difficult to understand and reason about.

Before you consider using a finalizer, you should understand everything in the following articles.

You could re-register for finalization in the destructor, like so:

~YourClass()
{
   System.GC.ReRegisterForFinalize(this);
}

And from there you'd probably want something to reference so it doesn't get finalized again, but this is a way to do it.

http://msdn.microsoft.com/en-us/library/system.gc.reregisterforfinalize(v=vs.110).aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top