Removal of WeakMap/WeakSet clear
kg at luminance.org
Thu Dec 4 20:00:55 PST 2014
JSIL has a shim that emulates the 2D portion of the XNA game
framework's graphics stack using HTML5 canvas (for compatibility).
Many of the stack's features don't have direct equivalents in canvas,
so I have to generate and cache various bits of data and graphics
resources on-demand to implement them.
A main use case here is that in order to do color multiplication of
bitmaps - typically used for
text rendering, but used in other cases as well - I have to take a
given image I intend to draw and split it into images for each
specific color channel (r, g, b, a) and keep the images around. The
lifetime of those images needs to be tied to the lifetime of the image
they are derived from, and I also need the ability to discard them in
response to memory pressure. WeakMap is near-perfect for this.
I have a complex garbage collection scheme where I manually maintain a
LRU cache of these images and discard the ones that have not recently
been used periodically, and when the cache gets too big I discard the
oldest ones. Ensuring this collector runs often enough without
discarding images too often is a real challenge.
A downside here is that these resources are very heap light (just
HTML5 canvases/images) but memory heavy. In the past I have found and
filed bugs related to this where a browser was not properly responding
to the memory pressure from these images. As a result of this I don't
use WeakMap for this feature anymore (but I used to).
Managing the memory pressure here is important so it is very valuable
to have both a way to clear out the entire cache (in response to the
graphics adapter being reinitialized or a pool of game content being
destroyed) and to remove a single value from the cache (in response to
a single image resource being destroyed). The clear scenario is
thankfully not common but it does happen. This is also an area where
the performance is a concern.
I have a similar caching scenario involving textures generated from
bitmap fonts + text strings but WeakMap can't solve that since JS
strings aren't object references. Oh well :-) That one has to use my
terrible hacked-together collector as a result regardless of memory
I do still use WeakMap in a few other places, for example to implement
Object.GetHashCode. This is a case where the transposed representation
is likely optimal - though in practice, I shouldn't need any sort of
container here, if only the hashing mechanisms clearly built into the
VM were exposed to user JS.
Out of the demos on the website, I think
http://hildr.luminance.org/Lumberjack/Lumberjack.html makes the most
significant use of the cache. The value below the framerate (measured
in mb) is the size of the bitmap resource cache. If the demo is
running using WebGL, the cache will be very small because WebGL needs
far fewer temporary resources. If you load
instead, it forces the use of the canvas backend and you will see the
cache becomes quite large during gameplay. I think this at least provides
a realistic scenario where you want a good WeakMap implementation that
responds well to all forms of memory pressure.
I also have a more recent use of WeakMap that is used to cache typed
array views for memory buffers. This is necessary to implement various
pointer manipulation scenarios, so that arbitrary data structures can
be unpacked from arbitrary offsets in a given array buffer. You can
effectively view this as a Typed Objects polyfill that predates the
Typed Objects spec work. I should note that this is something that
would be unnecessary if DataView were designed better, but things are
what they are. :)
On 4 December 2014 at 12:16, Mark S. Miller <erights at google.com> wrote:
> On Thu, Dec 4, 2014 at 6:25 AM, Katelyn Gadd <kg at luminance.org> wrote:
>> I should also note that while much of the above is speculative and
>> based on intuition/experience, I *have* been shipping a use of WeakMap
>> for performance-critical code for over a year now
> Hi Katelyn, could you say more about your shipping code? Is the code
> something your could post or make available? Thanks.
More information about the es-discuss