Dart Finalizer的作用
它和java的finalize方法有点像
/// 文件a
import 'dart:ffi';
import 'package:ffi/ffi.dart';
class FfiData {
/// Uint64的字节数
static const _sizeInBytes = 8;
/// 要是final的,因为它和FfiData对象是一对一共生的关系,FfiData对象被GC清理了,其内部的pointer也会被清理(清理逻辑自己写,通过Finalizer实现)
/// 如果要多个Isolate都用到malloc开辟的空间,这里改成final int address;比较合适;
final Pointer<Uint64> pointer;
/// 注意,这个是static final的,因为它充当着GC工具的作用,可以为多个FfiData对象清理内部引用的ffi数据,所以必须是static final的
static final _finalizer = Finalizer<Pointer<Uint64>>((ptr) {
/// 当当前的FfiData被GC释放时,会触发这里,这个是attach方法里绑定了这样的关系
print("释放了吗?${ptr.address}");
malloc.free(ptr);
});
void test() {
print("数据指针地址:${pointer.address}");
}
/// 在构造方法里allocate Pointer指向的空间数据
FfiData(): pointer = malloc.allocate(sizeOf<Uint64>()) {
// 注意这段代码,它表示注册当前FfiData对象,和这个FfiData对象释放后要传递给Finalizer初始化时的回调函数的对象
// 这样放this被GC释放时,DVM会拿到其对应的pointer对象,调用_finalizer初始化时的构造方法里的回调函数;
// attach是绑定this和pointer,还有个detach可以解绑,可以用于比如提前手动将pointer释放了,这个时候就要解绑了,不然会二次释放
_finalizer.attach(this, pointer);
}
}
/// 文件b
String template = "一段很长的内容";
void main() {
FfiData? data = FfiData();
data.test();
// 如果不设置为null会导致下面的循环虽然触发了GC,但是data被认为仍然有用而不会被释放,从而不触发对应的Finalizer对象的回调函数
data = null;
int size = 10000;
List<String> list = [];
// 用于触发GC
for (int i = 0; i < size; i++) {
list.add(template + i.toString());
}
print("size:${list.length}");
}
posted on 2023-10-13 10:11 Silentdoer 阅读(104) 评论(0) 编辑 收藏 举报