What is keeping an ArrayBuffer allocation alive in a Promise chain?

RESOLVED WORKSFORME

Status

()

Firefox
Developer Tools: Memory
RESOLVED WORKSFORME
9 months ago
9 months ago

People

(Reporter: Jukka Jylänki, Unassigned)

Tracking

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

(Reporter)

Description

9 months ago
Created attachment 8839738 [details]
capture_stack_memory.png

I'm trying to figure out why my page is keeping references to ArrayBuffers from downloaded XHRs, even though there should not be anything clinging on to them.

In particular, there is one 593984 byte ArrayBuffer allocation that should not exist, and there should not be any user objects that references that ArrayBuffer. The Memory tab shows a mysterious "scriptCode" field as the culprit, but I'm unable to understand what exactly is keeping this reference. See the attached screenshot for an illustration of what the Memory tool is saying about this.

STR:

1. Enable wasm in javascript.options.wasm;true in latest Nightly.
2. Open https://s3.amazonaws.com/mozilla-games/tmp/2017-02-21-SunTemple/SunTemple.html
3. After the page loads, there is an ArrayBuffer of size 593984 bytes that is held onto, but what is keeping that alive?

The Memory profiler suggests that there would be a function scope that'd be referencing it, but I am unable to figure out what scope exactly is the cause?
(Reporter)

Comment 1

9 months ago
In particular, the size of the file UE4Game-HTML5-Shipping.js.gz uncompressed is 592,934 bytes which is very close to that size, so it's likely that is the leaking XHR, but I don't see there being a function scope that would be capturing this? Expert help would be much appreciated on this, I'm scratching my head blank here.
(Reporter)

Comment 2

9 months ago
Phew, figured out the issue. Turns out the following code leaks whatever scriptCode is passed to it:

> function addScriptToDom(scriptCode) {
> 	return new Promise(function(resolve, reject) {
> 		var script = document.createElement('script');
> 		var objectUrl = URL.createObjectURL(new Blob([scriptCode], { type: 'text/javascript' }));
> 		script.src = objectUrl;
> 		script.onload = function() { URL.revokeObjectURL(objectUrl); resolve(); }
> 		script.onerror = function(e) { URL.revokeObjectURL(objectUrl); reject(e); }
> 		document.body.appendChild(script);
> 	});
> }
Status: NEW → RESOLVED
Last Resolved: 9 months ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.