SDK: who allocates & releases memory for max objects, MOP wrappers, jitter


    Mar 11 2016 | 12:42 pm
    In the Max 6.x and newer SDKs, what are the memory lifetime managers for max objects, MOP wrappers, and jitter objects? Specifically, who allocates and releases the memory for these three object structs? The SDK 6 and 7 docs are incomplete. Here is what I know or am guessing...
    Max objects created with t_class API using class_new()
    • C coder uses object_alloc(t_class *) to allocate memory for the struct and initialize it
    • ??? release of struct perhaps done internally by Max; because it is possible to pass NULL as the free function on class_new() so someone has to release it. Or is there a default free function that gets called when NULL is used?
    • ??? How can freeobject() or object_free() be used for releasing memory. Or the private object_release()? The header files suggest the first two call the free function. Therefore, if I were to call them in the free function, this might setup some sort of recursion.
    Max MOP wrapper objects created with t_class API using class_new()
    • C coder uses max_jit_object_alloc(t_class *) to allocate memory for the struct and initialize it
    • ??? release of struct perhaps done internally by Max; ditto as above
    • ??? How can freeobject() or object_free() be used for releasing memory. Or the private object_release()?
    • ??? What does max_jit_object_free() do in a free function defined via class_new()?
    jitter objects created with t_class API using jit_class_new()
    • C coder uses jit_object_alloc(t_class *) to allocate memory for the struct and initialize it
    • C coder uses jit_object_free(*) to release the struct
    --Dale

    • Mar 11 2016 | 4:46 pm
      Dale -
      Max objects created with t_class API using class_new()
      • C coder uses object_alloc(t_class *) to allocate memory for the struct and initialize ituse object_free() or freeobject() on the pointer returned from object_new() or a similarly allocated object
      • ??? release of struct perhaps done internally by Max; because it is possible to pass NULL as the free function on class_new() so someone has to release it. Or is there a default free function that gets called when NULL is used?yes, if you don't provide a free function, the struct memory will be automatically freed when object_free()/freeobject() is called
      • ??? How can freeobject() or object_free() be used for releasing memory. Or the private object_release()? The header files suggest the first two call the free function. Therefore, if I were to call them in the free function, this might setup some sort of recursion.don't ever call object_free() or freeobject() on an object in its own free function -- the free function is being called from object_free(). The free function is available so that you can free memory or teardown anything related to your object before it's reclaimed. object_release() is the balancing call to object_retain(), and, as documented, private and intended only for internal use
      Max MOP wrapper objects created with t_class API using class_new()
      • C coder uses max_jit_object_alloc(t_class *) to allocate memory for the struct and initialize it. if you use max_jit_object_alloc() to allocate your object in your new function, it should be balanced by a call to max_jit_object_free() in your free function
      • ??? release of struct perhaps done internally by Max; ditto as above yes
      • ??? How can freeobject() or object_free() be used for releasing memory. Or the private object_release()? jit_object_free() is, in versions of Max >=5 IIRC, an alias for object_free(), but for clarity you're are encouraged to balance your calls to jit_object_new() with jit_object_free()
      • ??? What does max_jit_object_free() do in a free function defined via class_new()? it balances a call to max_jit_object_alloc and frees resources allocated by that call (but not the object struct, which will be freed after the free function returns)
      jitter objects created with t_class API using jit_class_new()
      • C coder uses jit_object_alloc(t_class *) to allocate memory for the struct and initialize it yes
      • C coder uses jit_object_free(*) to release the structyes
    • Mar 11 2016 | 6:14 pm
      Is it true?.... that there is no way to release (aka free()) the object struct myself on basic CLASS_BOX objects and on Max MOP wrapper objects in the myobject_free() function or by any other means.
      All this memory digging is to find a way to align the object struct on 16-byte boundaries and to successfully release it. All the C language constructs to do that require specific core calls like aligned_malloc/aligned_free. Max core doesn't do C++. Another approach is to allocate more memory than I need in the xxx_object_alloc() calls, check and shift the object header data to an aligned location as needed, and then return that shifted memory address back to Max in the return value from the myobject_new().
      The problem lies in the release of the struct in both of those approaches. You imply above that Max does the free() on the struct and I can't stop that from happening. This leaves either an incompatible (malloc vs aligned_malloc) or a 8-byte offset (2nd approach with shifting) address in Max's core. The myobject_free() will be ok but when it jumps back into Max core code, the internal free() of the object struct will be undefined or fail.
      Can you think of a way I can achieve the aligning of the object struct? Can I hack/change Max's internal copy of the struct's memory address during the myobject_free(). It's probably in the jbox parent. But maybe it's elsewhere too...or not threadsafe to hack during the teardown.
      Today, I already have a sub-struct that I dynamically create/free and can therefore align it. This approach functions though it adds complexity and extra indirection. I would prefer to have the constant time cost O(1) of aligning on object create/free rather than today's O(n) cost at runtime.