Re: Intent to Ship: JavaScript weak references

235 views
Skip to first unread message

Shu-yu Guo

unread,
Apr 10, 2020, 7:00:55 PM4/10/20
to blin...@chromium.org, v8-...@googlegroups.com
+v8-dev with right email address.

On Fri, Apr 10, 2020 at 2:56 PM Shu-yu Guo <s...@google.com> wrote:

Contact

s...@chromium.org

gsa...@chromium.org

ma...@chromium.org


Explainer

https://v8.dev/features/weak-references

https://github.com/tc39/proposal-weakrefs/blob/master/README.md

https://github.com/tc39/proposal-weakrefs


Spec

https://tc39.es/proposal-weakrefs/

https://github.com/w3ctag/design-reviews/issues/321


Summary

WeakRefs adds two fundamentally new capabilities to JavaScript:


  1. Creating weak references to objects, with the WeakRef class

  2. Running user-defined finalizers after objects are garbage-collected, with the FinalizationRegistry class


These two features are intended to be advanced, power user features. They expose garbage collection (GC) behavior of the underlying implementation, and using them correctly takes careful thought. The W3C Tag Design Principles recommend against APIs that expose GC, and the champions of this feature recommend avoiding use of this feature if possible.


At the same time, weak references and observing finalizations are fundamental capabilities that cannot be expressed otherwise. This feature is best recommended to be used to avoid excess memory use and as a backstop against certain bugs, not as a normal way to clean up external resources or to observe allocation.


Notable semantics are as follows:


  • The WeakRef class is tailored for the web’s event-loop based programming. A dereferenced WeakRef referent is guaranteed to be alive until the end of the current turn of the event loop.

  • Finalization is post-mortem. Objects are not resurrectable.

  • Finalization callbacks are by default processed in asynchronous tasks in batches.

  • The ability to synchronously invoke finalizers is optional, and is pending discussion in HTML. WeakRefs will initially ship without this ability.


Please see the spec explainer and the V8 explainer for usage examples of the WeakRef and FinalizationRegistry classes as well as in depth semantics.


Is this feature supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

Yes


Debuggability

WeakRefs and FinalizationRegistries are JS objects and are thus inspectable. However, debugging weak references must be done very carefully, as the act of debugging itself and observing objects alters the garbage collection behavior. Debugging weak references and finalization is intrinsically difficult, and the author must not depend e.g. an object always being collected.


Interoperability Risk

This feature exposes garbage collection, and thus a degree of interoperability risk is unavoidable. However, the V8 team at Google, the JavaScriptCore team at Apple, and the SpiderMonkey team at Mozilla have worked together on the design of the API to minimize risk where possible.


This proposal reached Stage 3 at the June 2019 TC39.


Firefox: Partially implemented

Safari: Partially implemented

Web / Framework developers: Positive. Many WebAssembly uses hinge on being able to express weak references and finalization (e.g. vending handles of wasm objects to JS). GSuite is also interested.


Is this feature fully tested?

Tests exist in Test262: WeakRef and FinalizationRegistry. V8 has also cctests and mjsunit tests.

Preliminary web tests are in this CL, and Bocoup LLC is currently working on more comprehensive WPT tests for the HTML integration.


Note that any cross-implementation tests here are inherently nondeterministic. They cannot test that an object must be collected, only what must happen if an object is collected. An implementation that never GCs is compliant.


Tracking Bug

https://bugs.chromium.org/p/v8/issues/detail?id=8179


Feature Dashboard

https://www.chromestatus.com/features/5892186633666560

Shu-yu Guo

unread,
Apr 16, 2020, 6:25:45 PM4/16/20
to blin...@chromium.org, v8-...@googlegroups.com
Pinging thread for API OWNERS to take a look. :)

Shu-yu Guo

unread,
Apr 16, 2020, 6:27:20 PM4/16/20
to blink-dev
Pinging thread for API OWNERS to take a look. :)

Mike West

unread,
Apr 17, 2020, 2:10:48 AM4/17/20
to Shu-yu Guo, blink-dev
LGTM1.

I skimmed the notes from the June 2019 meeting, and the Feb 2020 meeting. Both seem to represent pretty reasonable agreement that this is the right direction for the feature. The TAG review seemed equally positive, and there seems to be recent activity on other vendors' implementations. I'm also happy to see substantial tests in Test262. I'd like to see y'all continue to push on https://github.com/web-platform-tests/wpt/issues/7899 and other dependencies so that the HTML integration can be reasonably tested as part of WPT as opposed to Chromium-specific web tests, but I don't think that's a blocker for shipping.

Thanks!
 
-mike


--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/ba38b271-348c-4d2e-abc7-af6458b9d751%40chromium.org.

Yoav Weiss

unread,
Apr 17, 2020, 4:12:41 AM4/17/20
to Mike West, Shu-yu Guo, blink-dev
LGTM2

That's a bit atypical.
What are the abuse cases we're concerned with? If it's related to developers relying on GC times specific implementations, are we planning to apply counter measures? (e.g. add some randomness to the time finalizers are called?)


At the same time, weak references and observing finalizations are fundamental capabilities that cannot be expressed otherwise. This feature is best recommended to be used to avoid excess memory use and as a backstop against certain bugs, not as a normal way to clean up external resources or to observe allocation.


Notable semantics are as follows:


  • The WeakRef class is tailored for the web’s event-loop based programming. A dereferenced WeakRef referent is guaranteed to be alive until the end of the current turn of the event loop.

  • Finalization is post-mortem. Objects are not resurrectable.

  • Finalization callbacks are by default processed in asynchronous tasks in batches.

  • The ability to synchronously invoke finalizers is optional, and is pending discussion in HTML. WeakRefs will initially ship without this ability.


I'm missing context on the last point - Are we talking about sync invocations when GC is running? Something else?
In any case, since this is not shipped with this intent, this is not a blocker. I'm just curious.


Please see the spec explainer and the V8 explainer for usage examples of the WeakRef and FinalizationRegistry classes as well as in depth semantics.


That's a great explainer! Extremely helpful in understanding what problem this is solving! 
 

Yulia Startsev

unread,
Apr 17, 2020, 4:56:17 AM4/17/20
to Yoav Weiss, Mike West, Shu-yu Guo, blink-dev
I will chime in from an outside perspective..


What are the abuse cases we're concerned with? If it's related to developers relying on GC times specific implementations, are we planning to apply counter measures? (e.g. add some randomness to the time finalizers are called?)

This is certainly a worry from a webcompat perspective. Introducing randomness, for example with tooling, would help ensure that developers do not depend on the GC behaviour of one browser.


  • The ability to synchronously invoke finalizers is optional, and is pending discussion in HTML. WeakRefs will initially ship without this ability.


I'm missing context on the last point - Are we talking about sync invocations when GC is running? Something else?

Yes, for example in a performance sensitive application, the developer might identify a moment when they can run some cleanup. The spec is mostly complete without this. This is primarily concerned with use cases of long running calculations. It might make sense to split this out in order to finish this behaviour.

- yulia


Shu-yu Guo

unread,
Apr 17, 2020, 5:15:40 PM4/17/20
to Yoav Weiss, Mike West, blink-dev
Indeed it's mostly related to developers coming to rely on specific GC timings from Chrome or Safari. Some countermeasures are built into the design of finalizers: they're scheduled as tasks on the main thread, so the time at which they run is decoupled from the time at which GC occurred.

Yulia's idea below about adding randomness when DevTools is open a good one, and I feel will go a long way in getting ahead of accidental dependence on GC timing. I will follow up with the Chrome DevTools team about this.
 


At the same time, weak references and observing finalizations are fundamental capabilities that cannot be expressed otherwise. This feature is best recommended to be used to avoid excess memory use and as a backstop against certain bugs, not as a normal way to clean up external resources or to observe allocation.


Notable semantics are as follows:


  • The WeakRef class is tailored for the web’s event-loop based programming. A dereferenced WeakRef referent is guaranteed to be alive until the end of the current turn of the event loop.

  • Finalization is post-mortem. Objects are not resurrectable.

  • Finalization callbacks are by default processed in asynchronous tasks in batches.

  • The ability to synchronously invoke finalizers is optional, and is pending discussion in HTML. WeakRefs will initially ship without this ability.


I'm missing context on the last point - Are we talking about sync invocations when GC is running? Something else?
In any case, since this is not shipped with this intent, this is not a blocker. I'm just curious.

No, not sync during when GC is running, but sync during the user script execution. By default, finalizers are scheduled by GC to run async in a task sometime after the current script has run to completion. cleanupSome is a way to synchronously invoke already-scheduled finalizers.
 


Please see the spec explainer and the V8 explainer for usage examples of the WeakRef and FinalizationRegistry classes as well as in depth semantics.


That's a great explainer! Extremely helpful in understanding what problem this is solving! 

Thank you for the kind words, all credit to Sathya Gunasekaran and Mathias Bynens.

Shu-yu Guo

unread,
Apr 17, 2020, 7:49:52 PM4/17/20
to Yoav Weiss, Mike West, blink-dev
A technical correction: finalizers are scheduled as tasks on the thread where the `FinalizationRegistry` is, not always the main thread.

Daniel Ehrenberg

unread,
Apr 20, 2020, 3:52:47 AM4/20/20
to blink-dev, mk...@chromium.org, s...@chromium.org


On Friday, April 17, 2020 at 10:12:41 AM UTC+2, Yoav Weiss wrote:

These two features are intended to be advanced, power user features. They expose garbage collection (GC) behavior of the underlying implementation, and using them correctly takes careful thought. The W3C Tag Design Principles recommend against APIs that expose GC, and the champions of this feature recommend avoiding use of this feature if possible.


That's a bit atypical.
What are the abuse cases we're concerned with? If it's related to developers relying on GC times specific implementations, are we planning to apply counter measures? (e.g. add some randomness to the time finalizers are called?)

Note, as part of the review process with the W3C TAG, the Client-side API Design Principles doc was updated to explain the fine line between the WeakRefs/FinalizationRegistry API (which is explicit and somehow scoped) and other APIs which incidentally expose GC in the course of doing other things (like getElementsByTagName). It's still recommended to *avoid* exposing GC, but we considered the API necessary to support certain use cases, so it's a tradeoff. I expect that we'll see tight scrutiny over future APIs which would expose GC in another way. https://github.com/w3ctag/design-principles/pull/129

The specification doesn't require implementations to add randomness. That was discussed at various times in the past, e.g., https://github.com/tc39/proposal-weakrefs/issues/14 . The specification *allows* these delays to be inserted, but it's generally expected that it would be impractical to turn this on in production all the time.

Chris Harrelson

unread,
Apr 20, 2020, 2:38:09 PM4/20/20
to Daniel Ehrenberg, blink-dev, Mike West, Shu-yu Guo
LGTM3

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

adilson couto

unread,
Jul 15, 2020, 1:48:03 PM7/15/20
to Shu-yu Guo, blin...@chromium.org, v8-...@googlegroups.com
--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
Reply all
Reply to author
Forward
0 new messages