"Managed" (コンパイルタイプ)
"Managed" (コンパイルタイプ)
"Managed"::[t]
自動メモリ管理を t に加える型を表す.
詳細
- "Managed"は外部ライブラリによって見せられる型等にメモリ管理を加える.
- t はすでに自動メモリ管理を持っていることはない.
- "Managed"はもう使用されないオブジェクトを自動的に解放するために自動参照カウントを使う.
- コンパイルされたコードから返された管理されたオブジェクトは,引き続きWolfram言語カーネルによってメモリ管理される.
- 管理されたオブジェクトはLibraryFunctionDeclarationによって宣言された関数の引数として渡されるとき,自動的にアンラップされる. »
コンストラクタ
- CreateTypeInstance["Managed"::[t],obj,freeFunc]は obj を含む管理されたオブジェクトを構築する.これは"Managed"オブジェクトが解放されるときにfreeFunc[obj]を実行する.freeFunc の型シグネチャは{t}"Null"でなければならない.
- CreateTypeInstance["Managed"::[t],obj]は freeFunc としてDeleteObjectを使う.
- 特定の"Managed"::[t]型のコンストラクタは多数あり,コンパイル型 t のページに文書化されている.例えば,"Managed"::["CString"]のコンストラクタは"CString"で述べられている.
特性
- 型"Managed"::[t]の man のInformation[man,"BaseType"]は"TypeSpecifier"::[t]を与える.
- UnmanageObjectは管理されたオブジェクトをアンラップして無効化し,ラップされたオブジェクトの所有権を取る.
UnmanageObject[man]は man["UnmanageObject"]と等しい.
ランタイムエラー
- 管理されていたオブジェクトを,UnmanageObjectで管理されなくなった後に使うとランタイムエラーが生じることがある.
InvalidManaged
例題
すべて開く すべて閉じる例 (3)
管理された"CString"オブジェクトを返すプログラムをコンパイルする:
cf = FunctionCompile[Function[Typed[str, "String"],
Cast[str, "Managed"::["CString"]]
]]cf["Hello, World!"]ラップされた"CString"は,管理されたオブジェクトが範囲外になると自動的に解放される:
With[{before = MemoryInUse[]}, Do[cf["test"], 100];MemoryInUse[] - before]解放されたときに出力する,管理されたオブジェクトを返す関数をコンパイルする:
cf = FunctionCompile[Function[{},
CreateTypeInstance["Managed", 12, Function[obj, Echo["freed"];]]
]]Module[{obj}, obj = cf[];Echo["body"]];文字列を管理されたC文字列に変換して借用された値を使うことによって,文字列の長さを返す関数をコンパイルする:
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!"]スコープ (4)
管理されたオブジェクトはコンパイルされたコードでメモリ管理される:
cf = FunctionCompile[Function[{},
Module[{obj},
obj = CreateTypeInstance["Managed", 12, Function[obj, Echo["freed"];]];
Echo["body"];
]
]]cf[]管理されたオブジェクトのコンテンツにはUnmanageObjectでアクセスすることができる:
createManaged = FunctionCompile[Function[{},
CreateTypeInstance["Managed", 12, Function[obj, Echo["freed"];]]
]]unmanage = FunctionCompile[Function[Typed[arg, "Managed"::["MachineInteger"]],
UnmanageObject[arg]
]]man = createManaged[]UnmanageObjectでコンテンツを抽出する:
unmanage[man]UnmanageObjectは管理されたオブジェクトを無効にするので,その後のUnmanageObjectの呼出しは失敗する:
unmanage[man]以前は管理されていなかった管理されたオブジェクトは自動的に解放されない.管理されたオブジェクトを作成し,管理されなくする関数をコンパイルする:
createManaged = FunctionCompile[Function[{},
CreateTypeInstance["Managed", 12, Function[obj, Echo["freed"];]]
]]unmanage = FunctionCompile[Function[Typed[arg, "Managed"::["MachineInteger"]],
arg["UnmanageObject"]
]]Module[{obj}, obj = createManaged[];Echo["body"]];Module[{obj}, obj = createManaged[];unmanage[obj];Echo["body"]];dec = LibraryFunctionDeclaration["sumArray", "compilerDemoBase", {"CArray"::["CLong"], "CLong"} -> "CInt"];管理されたC配列が借用され,ライブラリ関数に渡される前に自動的にアンラップされる:
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)
管理されていなかった管理オブジェクトから値を借用するとエラーが起こる.管理オブジェクトから値を作成,非管理,借用するための関数をコンパイルする:
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]管理されていないオブジェクトのコンテンツを借用するとエラーになる:
borrow[man]テクニカルノート
履歴
2022 で導入 (13.1)