How does garbage collection work?

Planned

Comments

5 comments

  • Julian Adams

    The garbage collector cleans up unreferenced strings, arrays, structs, methods, and probably some other stuff too. It is not intended to target data structures nor buffers nor surfaces - basically any existing functionality that has explicit create() and destroy() functions.

    YYG probs need to be more precise with their messaging here because this *will* confuse people.

    1
    Comment actions Permalink
  • Gurpreet Matharoo

    Got it, thanks Julian!

    So if garbage collection isn't supposed to free the dynamic resources created inside class structs, then we really need deconstructors...

    1
    Comment actions Permalink
  • Core Tech

    We have no plans to introduce destructors (in the short, medium and long term), there are many reasons for this as destructors in a garbage collected environment can cause a lot more problems than they appear to solve as it is they run at an indeterminate time (when the object is forgotten, which can easily be a lot later than the user really wants the resource tied up, it would be better handled with explicit user resolution), also it has issues when the code in the destructor actually causes the object to be referenced again so the object is no longer collected (so the destructor can be called more than once, this would be very confusing for many of our users).

    GML is very like Javascript and that does not have destructors for similar reasons - see https://stackoverflow.com/questions/29333017/ecmascript-6-class-destructor for a discussion on this

    In the long term we are looking to provide new data structure functionality (though now I would argue that most uses of ds_lists can be replaced with arrays and maps with structs) and these would be garbage collected properly as they would be based on struct functionality (like sequences are).

    Russell

     

    0
    Comment actions Permalink
  • Core Tech

    I would advocate using an IDispose like design pattern where resources are allocated and released explicitly, something like this (in javascript) https://gist.github.com/Antaris/7869718

    I am considering adding another accessor [$ ] which would allow structs members to be referred to easily (set or get) so 

    struct[$ "foo" ] = 10;

    would be the same as variable_struct_set( struct, "foo", 10 ) and 

    a = struct[$ "foo" ];

    would be the same as a = variable_struct_get( struct, "foo" );

    This should simplify replacing ds_maps with structs in many cases.

    NOTE : The beta version that is about to come out supports the variable_struct... set of functions

    Russell

    0
    Comment actions Permalink
  • Julian Adams

    I started poking around seeing what's possible with "delete" to perhaps construct some sort of "watcher" system that'd monitor when structs get GC'd.

    Consider:

    A = {list : ds_list_create()};
    B = A;
    delete A;
    show_debug_message(B); // { list : 0 }

    I had hoped that B would come back as "undefined", but when reasoning out the behaviour here (https://help.yoyogames.com/hc/en-us/community/posts/360008765638--delete-question-probably-caused-by-lack-of-documentation) I realised that wasn't going to be possible as A and B hold different references to the struct, and "delete" is only really hinting to the GC that the struct should be considered for freeing.

    If it was possible to make a reference to the struct without the GC acknowledging the reference as needing to keep the struct alive, then there's a workable design pattern to clean up resources orphaned by dead structs e.g.

    A = {list : ds_list_create()};
    array = [struct_ref(A), A.list];
    delete A;
    /// ### Step ###
    if (!is_struct(struct_deref(array[0]))) ds_list_destroy(array[1]);

    Feels like a workaround to a deeper issue though.

    0
    Comment actions Permalink

Please sign in to leave a comment.