-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Finalizer vs. NativeFinalizer #52436
Comments
Ad 1. @dcharkes? Ad 2. The
|
RE 1: I've edited your matrix.
"Guaranteed to be called in a timely manner", if you write code that doesn't allocate a whole lot (e.g. only some small integer manipulation in an existing data structure, or just a bunch of async that is doing nothing waiting on some timer to expire) it is entirely possible long stretches of time go without GC. So, the native finalizers are not guaranteed to be running in a timely manner. RE 2: Indeed, if you only have Dart code, you can only use RE 3: Instead, you should have a
You can't callback into Dart from the C function that is being run as native finalizer. You could send a message back to dart asynchronously with a native port. Your specific ask about using an allocator is being tracked on: |
Can you explain what is "premature finalization"? The term "finalization" is being used in the docs without being defined clearly what it means in the context. I still don't fully understand the use cases for If that's the case, am I correct to say that it's still on the users to make sure every |
Maybe we should consider replacing the example with something purely dart. Yes, that why for native resources (like a sqlite3 database or query handle) we should use For Dart resources (let's say some hashmap cache) we can use normal finalizers. If the isolate shuts down, all objects will be gone anyway.
class MyDatabase implements Finalizable {
Pointer<Void> database;
MyDatabase() // attaches finalizer
}
void main() {
final db = MyDatabase(...);
db.query(...);
}
// Now, the dart compiler might realize it can inline db.query(...);
void main() {
final db = MyDatabase(...);
final pointer = db.database;
someFffCallForQuery(pointer, ...);
}
// And the garbage collector might run before the query.
void main() {
final db = MyDatabase(...);
final pointer = db.database;
// GC runs, collects `db`, and runs the finalizer, which calls a close/release on the native database.
someFffCallForQuery(pointer, ...); // uses `pointer` after the native database has been closed -> crash
}
I don't know if Flutter cleans up it's native resources when the wrapper objects are GCed. In Dart we do for example for |
I'm having a hard time understanding the exact differences between
Finalizer
(docs) andNativeFinalizer
(docs). Here's a feature matrix I created, based on the officials documentation and a bit of guesswork.Finalizer
NativeFinalizer
Finalizable
Finalizer
docs make a point of stressing how very unreliable it is. Why would one ever chooseFinalizer
overNativeFinalizer
?package:ffi
offers handycalloc
andcalloc.free
functions. Given thatNativeFinalizer
only supports native callback functions, it seems that there is no way to reliably have a non-native free function called -- unless I were to wrap the Dart function in a native function just to be able to pass it toNativeFinalizer
. Is this correct?The text was updated successfully, but these errors were encountered: