-
Notifications
You must be signed in to change notification settings - Fork 6k
[web] fix SkFinalizationRegistry for dart2js (attempt 4) #40938
Conversation
|
Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change). If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review. |
|
|
||
| /// Collects native objects that weren't explicitly disposed of using | ||
| /// [UniqueRef.dispose] or [CountedRef.unref]. | ||
| SkObjectFinalizationRegistry _finalizationRegistry = createSkObjectFinalizationRegistry( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mentioned this offline, but perhaps it would be a bit less fragile to do the following:
- Make this variable nullable
- Guard the construction of this object by
browserSupportsFinalizationRegistry, otherwise return null - Have any uses of this object (i.e.
registerbelow) do a null check instead ofbrowserSupportsFinalizationRegistry
That feels a little less fragile, because right now if someone accidentally touches this variable without checking browserSupportsFinalizationRegistry first they could cause things to explode. A nullable variable would let the static type system save you from accidentally doing that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this _finalizationRegistry ever intended to be used from outside the NativeMemoryFinalizationRegistry facade though? If it's only used from the facade, I think this is safe enough as is (famous last words? :P)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to fix it as a follow-up. For now there's no risk of this variable being touched by accident, because it's private. But in general, I like the idea of explicit lazy initialization.
eyebrowsoffire
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I wonder if it would be worthwhile to emit a warning to console if FinalizationRegistry is not supported?
I think this is a warning worth adding, especially because FinalizationRegistry is fairly recent on iOS Safari (14.5 according to MDN). |
ditman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RSLGTM, good luck! (Please create an issue with whatever fast-follows you want to do on top of this PR, like Jackson's null-safety suggestion or adding the warning)
eyebrowsoffire
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My comments are not blocking, we can always follow up if needed.
That's a good idea. I'll do it as a follow-up. I realized that we should have similar warnings when |
|
Flutter Gold stuff is a know Impeller flakines, so merging manually. |
(this is attempt 4; details below)
Remove obsolete object caches and introduce a simpler way to manage native objects:
SynchronousSkiaObjectCache.native_memory.dartthat's smaller and simpler thanskia_object_cache.dart.UniqueRefa reference with a unique Dart object owner.CountedRefa ref-counted reference with multiple Dart object owners.FinalizationRegistry) as a back-up.FinalizationRegistry. All browsers support it now.SkParagraphcache that predates the introduction ofParagraph.dispose.CkParagraphin terms ofUniqueRef.CkImagein terms ofCountedRef; deleteSkiaObjectBox.This PR does not migrate all objects from the old
skia_object_cache.darttonative_memory.dart. That would be too big of a change. The migration can be done in multiple smaller PRs.This also removes a few unnecessary relayouts observed in flutter/flutter#120921, but not all of them (more details in flutter/flutter#120921 (comment))
About attempt 4
More info about the revert of attempt 3 in #40937.
In this attempt I check that the browser supports
FinalizationRegistrybefore registering the object. This will allow the code to run in older browsers, but there will be no protection from memory leaks when the app fails to dispose of the respective objects.Benchmarks
Now that this landed in flutter/flutter I have some benchmark numbers from the devicelab. The
text_out_of_picture_boundsbenchmark dropped by 3-4x (lower is better):The repro provided in flutter/flutter#123204 dropped from 110ms/frame to 10ms/frame.