-
See Also
- UnmanageObject
- CreateTypeInstance
-
- Compiled Types
- CArray
- CString
- Related Guides
- Tech Notes
"Managed" (Compiled Type)
"Managed"::[t]
represents a type that adds automatic memory management to t.
Details
- "Managed" adds memory management to types, such as those exposed by external libraries.
- t cannot already have automatic memory management.
- "Managed" uses automatic reference counting to automatically free objects that are no longer in use.
- Managed objects returned from compiled code continue to be memory managed by the Wolfram Language kernel.
- Managed objects are automatically unwrapped when passed as arguments to functions declared by LibraryFunctionDeclaration. »
Constructors
- CreateTypeInstance["Managed"::[t],obj,freeFunc] constructs a managed object containing obj, which executes freeFunc[obj] when the "Managed" object is freed. freeFunc must have the type signature {t}"Null".
- CreateTypeInstance["Managed"::[t],obj] uses DeleteObject as the freeFunc.
- There are many constructors for specific "Managed"::[t] types, which are documented on the page for the compiled type t. For example, constructors for "Managed"::["CString"] are documented with "CString".
Properties
- Information[man,"BaseType"] for man of type "Managed"::[t] gives "TypeSpecifier"::[t].
- UnmanageObject unwraps and invalidates a managed object, taking ownership of the wrapped object.
UnmanageObject[man] is equivalent to man["UnmanageObject"].
Runtime Errors
- Using a managed object after it has been unmanaged with UnmanageObject can give a runtime error.
InvalidManaged
Examples
open all close allBasic Examples (3)
Compile a program that returns a managed "CString" object:
cf = FunctionCompile[Function[Typed[str, "String"],
Cast[str, "Managed"::["CString"]]
]]cf["Hello, World!"]The wrapped "CString" is automatically freed when the managed object goes out of scope:
With[{before = MemoryInUse[]}, Do[cf["test"], 100];MemoryInUse[] - before]Compile a function that returns a managed object that prints when it is freed:
cf = FunctionCompile[Function[{},
CreateTypeInstance["Managed", 12, Function[obj, Echo["freed"];]]
]]Create the managed object and then let it pass out of scope:
Module[{obj}, obj = cf[];Echo["body"]];Compile a function that returns the length of a string by casting the string to a managed C-string and using its borrowed value:
func = FunctionCompile[
Function[{Typed[str, "String"]}, Module[{cstrMan, cstr, len}, cstrMan = Cast[str, "Managed"::["CString"]];
cstr = cstrMan["BorrowValue"];
len = LibraryFunction["strlen"][cstr];
len
]
]
]func["Hello, World!"]Scope (4)
Managed objects are memory managed in compiled code:
cf = FunctionCompile[Function[{},
Module[{obj},
obj = CreateTypeInstance["Managed", 12, Function[obj, Echo["freed"];]];
Echo["body"];
]
]]cf[]The contents of managed objects can be accessed with UnmanageObject:
createManaged = FunctionCompile[Function[{},
CreateTypeInstance["Managed", 12, Function[obj, Echo["freed"];]]
]]unmanage = FunctionCompile[Function[Typed[arg, "Managed"::["MachineInteger"]],
UnmanageObject[arg]
]]man = createManaged[]Extract its contents with UnmanageObject:
unmanage[man]UnmanageObject invalidates the managed object, so subsequent calls to UnmanageObject fail:
unmanage[man]Managed objects that have been unmanaged are not automatically freed. Compile functions for creating and unmanaging a managed object:
createManaged = FunctionCompile[Function[{},
CreateTypeInstance["Managed", 12, Function[obj, Echo["freed"];]]
]]unmanage = FunctionCompile[Function[Typed[arg, "Managed"::["MachineInteger"]],
arg["UnmanageObject"]
]]Create a managed object and then let it pass out of scope:
Module[{obj}, obj = createManaged[];Echo["body"]];Unmanage the object before letting it pass out of scope:
Module[{obj}, obj = createManaged[];unmanage[obj];Echo["body"]];Represent a function that takes an unmanaged C array as an argument:
dec = LibraryFunctionDeclaration["sumArray", "compilerDemoBase", {"CArray"::["CLong"], "CLong"} -> "CInt"];The managed C array is borrowed and automatically unwrapped before it is passed to the library function:
cf = FunctionCompile[dec,
Function[Typed[arg, "ListVector"::["CLong"]],
Module[{carr},
carr = CreateTypeInstance["Managed"::["CArray"::["CLong"]], arg];
LibraryFunction["sumArray"][carr, Length[arg]]
]
]
]cf[Range[100]]Possible Issues (1)
Borrowing values from managed objects that have been unmanaged results in an error. Compile functions for creating, unmanaging and borowing values from a managed object:
createManaged = FunctionCompile[Function[{},
CreateTypeInstance["Managed", 12, Function[obj, Echo["freed"];]]
]]unmanage = FunctionCompile[Function[Typed[arg, "Managed"::["MachineInteger"]],
arg["UnmanageObject"]
]]borrow = FunctionCompile[Function[Typed[arg, "Managed"::["MachineInteger"]],
arg["BorrowValue"]
], CompilerRuntimeErrorAction -> None]man = createManaged[]unmanage[man]Borrowing the contents of an unmanaged object is an error:
borrow[man]Tech Notes
Related Guides
History
Introduced in 2022 (13.1)