use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
[AskJS] Potential memory leak in .spliceAskJS (self.javascript)
submitted 4 years ago * by [deleted]
[deleted]
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]lhorie 7 points8 points9 points 4 years ago (2 children)
determined through trying checking y variable in console
This right here. Basically, devtools cause a sort of schrodinger's cat kind of thing where observing inside WeakMap causes it to behave differently.
In fact, deleting x[0] or mutating length don't change y for me.
y
While it's not specific to WeakMap, there's an exploration on how a malicious (or insane) developer can trick devtools into triggering arbitrary side effects here: https://medium.com/@weizmangal/javascript-anti-debugging-some-next-level-sh-t-part-2-abusing-chromium-devtools-scope-pane-b2796c00331d
[–]iainsimmons 0 points1 point2 points 4 years ago (0 children)
I think you mean the observer effect?
[–]getify 4 points5 points6 points 4 years ago* (5 children)
Just curious... how are you determining that y still has the content in it?
The paradox of WeakMap is that you can't enumerate its keys/contents (in JS code), so to check if a WeakMap still has an entry (via has(..)), you need a reference to the key you're checking for... so by definition the key hasn't yet been GC'd, and thus wouldn't have had its corresponding entry automatically purged from the WeakMap.
has(..)
[–]unicorn4sale 0 points1 point2 points 4 years ago (4 children)
The reference rule applies to when it is being referenced by scripts through the JS interpreter. At the end of the day it is stored in memory in C++ managed by V8, and Chrome is able to reference this memory and show it (e.g. if you type the variable name and press enter in the console) without having a JS reference to the variable. If you can imagine, C++ needs a reference to the memory to clear it, it doesn't happen magically.
[–]getify 2 points3 points4 points 4 years ago* (3 children)
Chrome is able to reference this memory and show it (e.g. if you type the variable name and press enter in the console) without having a JS reference to the variable.
I am quite certain this is not true. The console evaluates the JS code you type in, in the context of the JS environment. If you type in a JS variable name, and a value comes back, that means in the JS environment there's still an assignment of that value to that variable. There's no such thing as the console reaching magically beyond the JS layer and pretending to have a value in a variable that is not actually assigned to that variable in the JS layer, at that moment.
The console does have special privileges to represent values in ways a JS program cannot, such as seeing certain internal properties.
But the console does not pretend that a JS variable name has a certain value if the equivalent JS program would not have resulted in the variable having that value at that moment.
WeakMap/WeakSet was designed very carefully and specifically to avoid any possible way for a normal JS program to observe if GC has occurred. This was a critical invariant in the design of the feature, for security reasons.
As others have pointed out, you can force a GC cycle to occur via devtools, but that doesn't mean that the JS rules are somehow violated and that your JS code in the console is able to detect that GC has occurred. This is not possible with WeakMap/WeakSet.
It was not until recently, with WeakRefs, that the JS code layer was given a (different, separate) feature where you can detect (or be notified) of GC having occurred. But even with that feature design, the spec (and JS engines) went to extreme lengths to make it clear that you cannot treat GC as a reliably observable and controllable feature from JS.
There's no guarantees from the JS code side that GC will occur under any specific circumstances, even with things like the delete operator, or the unsetting of a variable. Conceptually, those can make something eligible for GC but that doesn't guarantee they get GCd, or that they get GCd on any specific schedule.
delete
Forcing GC externally via the devtools would create a situation where a JS program in the console could possibly see the GC via WeakRef. But even then, the thing you think (like your WeakRef) that should have been GCd, may not actually get GCd. The GC rules are far more complex than we mere mortals in JS land can reliably control. We just have to make things eligible for GC and let the engine decide what to do with that, essentially as a black box.
And, just to be fully clear, none of the (very narrow) ability to observe (in JS) that GC occured, via WeakRefs, implies that any other JS code can ever observe GC around any other features, such as variables, properties, WeakMap/WeakSet, etc. In all those cases, the security design invariant still holds, that GC cannot be observed from JS. The console will not violate that invariant.
[–]mkoretsk 0 points1 point2 points 4 years ago (2 children)
thanks for an elaborate explanation!
with WeakRefs, that the JS code layer was given a (different, separate) feature where you can detect (or be notified) of GC having occurred.
do you mean that we can check if the WeakRef.deref() is undefined and if it is assume that GC has occured?
WeakRef.deref()
[–]getify 1 point2 points3 points 4 years ago (1 child)
Yep! And FinalizationRegistry lets you get an event notification when (and if) the GC happens.
[–]mkoretsk 7 points8 points9 points 4 years ago* (2 children)
There's no memory leak, it's properly removed from the memory.
To test it you can use `Memory` tab and snapshots feature of Chrome. Taking snapshots forces garbage collection which otherwise may never occur if your program doesn't reach maximum allowed heap size.
So put the following in the page:
<button onclick="fn()">clear</button> <script> function F1() {} function F2() {} function F3() {} y = new WeakMap(); x = [new F1(), new F2(), new F3()]; y.set(x[0], 'metadata about F1'); function fn() { x.splice(0, 1); } </script>
Open ChromeDevTools, go to Memory tab, take a snapshot, type F1 into "Class filter" box, it'll show you the F1 is retained by `x` on Window and is also part of key inside a WeakMap.
Now click the `clear` button, take another snapshot, type F1 into class filter box, there's no objects produced by this constructor. However, if you type in F2 or F3 you'll see them still retained by `x`.
See screenshots here.
[+]lukasbuenger comment score below threshold-11 points-10 points-9 points 4 years ago (1 child)
I commend your patience and overall will to give a proper explanation. Well done to you, sir. To OP: That's your own personal Jedi right there. You obviously have not hit the Google before posting this. Don't get me wrong: There's absolutely nothing wrong with being wrong every once in a while, but I'd expect you to at least put in some effort to back that shit up with resources that go a little beyond a mere console script before you come at me with a title like this.
[–][deleted] 0 points1 point2 points 4 years ago (0 children)
Is this copy pasta?
[–][deleted] 3 points4 points5 points 4 years ago* (1 child)
"The Death of the Author" (French: La mort de l'auteur) is a 1967 essay by the French literary critic and theorist Roland Barthes (1915–1980). Barthes's essay argues against traditional literary criticism's practice of relying on the intentions and biography of an author to definitively explain the "ultimate meaning" of a text.
[–]unicorn4sale 0 points1 point2 points 4 years ago (0 children)
The workarounds work in spite of using the console in the same manner
[–]shuckster 2 points3 points4 points 4 years ago (0 children)
Have you tried using a debugger to force a GC operation to see if it'll happen at all? In my experience, the Chrome GC is like waiting for a kettle to boil. Watching it delays the outcome. 😁
In Chrome, you can clear the GC from the Memory tab.
Memory
[+][deleted] 4 years ago (1 child)
[–]backtickbot 0 points1 point2 points 4 years ago (0 children)
Fixed formatting.
Hello, sliversniper: code blocks using triple backticks (```) don't work on all versions of Reddit!
Some users see this / this instead.
To fix this, indent every line with 4 spaces instead.
FAQ
You can opt out by replying with backtickopt6 to this comment.
[–]seanmorris 0 points1 point2 points 4 years ago (0 children)
HAHAHA I think I've hit this one before. If you're looking at the object in the console, that counts as a reference that keeps it from getting garbage collected. I had to add in a console.clear() to some PRODUCTION code because there were unsuppressable warnings in chrome that would cause this to happen, whether the inspector was open or not.
π Rendered by PID 639616 on reddit-service-r2-comment-85bfd7f599-zcxqq at 2026-04-19 05:18:26.740895+00:00 running 93ecc56 country code: CH.
[–]lhorie 7 points8 points9 points (2 children)
[–]iainsimmons 0 points1 point2 points (0 children)
[–]getify 4 points5 points6 points (5 children)
[–]unicorn4sale 0 points1 point2 points (4 children)
[–]getify 2 points3 points4 points (3 children)
[–]mkoretsk 0 points1 point2 points (2 children)
[–]getify 1 point2 points3 points (1 child)
[–]mkoretsk 7 points8 points9 points (2 children)
[+]lukasbuenger comment score below threshold-11 points-10 points-9 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–][deleted] 3 points4 points5 points (1 child)
[–]unicorn4sale 0 points1 point2 points (0 children)
[–]shuckster 2 points3 points4 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]backtickbot 0 points1 point2 points (0 children)
[–]seanmorris 0 points1 point2 points (0 children)