locked
Preserving data from GC RRS feed

  • Question

  • Hi all,

    I have a Matrix class that holds 3 vectors. I want to be able to transfer these vectors to somewhere else if the Matrix itself is destroyed by the GC.

    Is this possible? Is there a way to know before an object is destroyed? Using a destructor would do? Or destructors are called after the object is destroyed?

    So it will be like this:

    myMatrix = Matrix3x3 (v1,v2,v3)

    Preserved(v1,v2,v3)


    myMatrix is no more...




    Thanks,
    Aw
    Wednesday, May 28, 2008 4:40 PM

Answers

  • Sounds to me more like a factory method/pattern would be better, it would certainly be more maintainable.  Playing with Finalize and WeakReference has issues and is hard to maintain.

     

    Instead of being able to create Matrix3x3 object via it's constructor you use a factory method (which can be a static on the class).  For example:

    Code Snippet

     

    public class Matrix3x3 {

      private Matrix3x3(int v1, int v2, int v3) {

        // TODO:

      }

      private static Matrix3x3 TryGetFromCache(int v1, intv2, int v3) {

        // TODO:

      }

      private static void AddToCache(Matrix3x3 matrix) {

        // TODO:

      }

     

      // Factory method to create/reuse a Matrix3x3 object.

      public static Matrix3x3 Create(int v1, int v2, int v3) {

        Matrix3x3 result = TryGetFromCache(v1, v2, v3);

        if(result == null) {

           result = new Matrix3x3(v1, v2, v3);

           AddToCache(result);

        }

        return result;

      }

    }

     

     

    This is more explicit and avoids having to delve into WeakReference or playing with Finalize (bad).

     

    • Proposed as answer by Joan Venge Friday, May 30, 2008 6:02 PM
    • Marked as answer by Joan Venge Friday, May 30, 2008 6:02 PM
    Thursday, May 29, 2008 3:23 PM
    Moderator

All replies

  • Just keep a reference to the vectors somewhere.
    By definition, the matrix won't be eligible for GC until after you've lost any remaining references to it, and thus the vectors are no longer reachable either.

    Why specifically do you need to keep them like this? Why can't you simply store some references to them somewhere?
    Wednesday, May 28, 2008 4:48 PM
  • I am thinking of cases like this:

    Someone says:

    myMatrix = null

    or

    myMatrix goes out of scope

    I want my vectors back.

    But if the vectors are still around, myMatrix will not be eiligble for GC?





    Thanks,
    Aw
    Wednesday, May 28, 2008 4:55 PM
  • Sounds like you want to use a WeakReference.

     

    Wednesday, May 28, 2008 7:51 PM
    Moderator
  • Thanks Peter, I read about it now. It's unfamiliar to me.

    But basically I will be able to create an empty cache and then populate it with "supposedly disposed" elements, right?





    Thanks again,
    Aw
    Wednesday, May 28, 2008 8:07 PM
  • Hi Peter,

    Now I read through the code, and it looks like it's using the cache if there is object there, or else if the object si destroyed then it creates another one, right?

    Because what I want to do is avoid creating new objects if the number of created objects are already enough to handle the live objects. So say I have 10 Matrix3x3 containing for a total of 30 vector3 objects. If 4 of them are destroyed and the user creates 4 new Matrix3x3 objects, then the vector3 objects that I gathered from the disposed Matrix3x3 objects will be enough to handle the new vector3 object that will be used in the new 4 Matrix 3x3.

    Make sense?





    Thanks,
    Aw
    Wednesday, May 28, 2008 10:35 PM
  • Peter,

    I also noticed WeakReference is an object collection, right? That means you have to box/unbox? Wouldn't it cost more than what I would gain by the optimization I am making?




    Thanks,
    Aw
    Thursday, May 29, 2008 12:54 AM
  • I think I have found what I need: Finalize method. I am not sure totally since I haven't used it before but it sounds like it.

    I am still looking forward to your replies and opinions though.




    Thanks,
    Aw
    Thursday, May 29, 2008 1:01 AM
  •  Azurewrath wrote:
    I think I have found what I need: Finalize method. I am not sure totally since I haven't used it before but it sounds like it.

    I am still looking forward to your replies and opinions though.




    Thanks,
    Aw

     

    Hi!

     

    You have two options here:

    1. Use System.Runtime.InteropServices.GCHandle class. With this class you can manage lifetime of your matrix instance.

    2. You can play with resurrection (but be careful with it). For instance:

    ~Matrix()

    {

    someStaticExternalVariable.Matrix = this;

    GC.ReRegisterForFinalize(this);

    }

    Thursday, May 29, 2008 7:28 AM
  • Sounds to me more like a factory method/pattern would be better, it would certainly be more maintainable.  Playing with Finalize and WeakReference has issues and is hard to maintain.

     

    Instead of being able to create Matrix3x3 object via it's constructor you use a factory method (which can be a static on the class).  For example:

    Code Snippet

     

    public class Matrix3x3 {

      private Matrix3x3(int v1, int v2, int v3) {

        // TODO:

      }

      private static Matrix3x3 TryGetFromCache(int v1, intv2, int v3) {

        // TODO:

      }

      private static void AddToCache(Matrix3x3 matrix) {

        // TODO:

      }

     

      // Factory method to create/reuse a Matrix3x3 object.

      public static Matrix3x3 Create(int v1, int v2, int v3) {

        Matrix3x3 result = TryGetFromCache(v1, v2, v3);

        if(result == null) {

           result = new Matrix3x3(v1, v2, v3);

           AddToCache(result);

        }

        return result;

      }

    }

     

     

    This is more explicit and avoids having to delve into WeakReference or playing with Finalize (bad).

     

    • Proposed as answer by Joan Venge Friday, May 30, 2008 6:02 PM
    • Marked as answer by Joan Venge Friday, May 30, 2008 6:02 PM
    Thursday, May 29, 2008 3:23 PM
    Moderator
  • Thanks Peter.

    It looks like this might do it but I am still unsure about these:

    The matrixes have the vector3s in themselves. Before a matrix gets destroyed, I have to get the vector3s to somewhere else so that the GC doesn't destroy them. But when can I do it if I don't know when the GC occurs, right?





    Thanks,
    Aw
    Friday, May 30, 2008 6:06 PM
  • Hey all,

    I was using Finalize and like both Peter and the VS warned me not to use it, I used a destructor instead. Isn't destructor gets called before GC destroys the object? Is it always guaranteed to be called? Because I read about the Finalize not guaranteed to be called. Not sure if it's the case for the destructor.





    Thanks.
    Monday, June 2, 2008 6:02 PM