-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Turning my discussion with @hterkelsen into a github issue.
In Flutter mobile when a Dart object is garbage collected we get a signal from the VM so we can clean up (or bump the refcount down to) the corresponding C++ object. For example, when a Picture is no longer used by the framework, the C++ can free it. This is not support by JavaScript. When we compile for the web JS does not tell us when framework-side objects are collected. To combat this limitations we use two approaches:
- For objects that we can restore from Dart-side data we delete the C++ objects, and if the framework reuses it again, we "resurrect" the object by constructing a new one from the data that we keep on the JS side.
- For objects that we cannot restore, we keep them in a LRU cache, and delete them when the cache evicts the object.
The first approach is always correct (it doesn't leak memory, not does it result in dangling pointers), but it's not always efficient (some objects are expensive to delete and resurrect).
The second approach is efficient (we don't need to resurrect objects) but it's not always correct (it leads to a dangling pointer when the LRU cache decides to evict an object that's still in use).
We should aim at being always correct and as efficient as possible.
One option is to use a hybrid between the two approaches: make all objects resurrectable but use an LRU cache to reduce the delete/resurrect cycles for frequently used objects. This can be further enhanced by scheduling the serialization of the data from the WASM heap into the JS heap in a requestIdleCallback (only needed for objects that need serialization in the first place; some don't).
/cc @hterkelsen please feel free to correct if I captured something incorrectly.