I am diagnosing a memory leak in a jQuery based single page application using the Chrome DevTools heap snapshot tool as described on
I have solved some issues this way, but I have now hit a roadblock where I can no longer determine what is keeping an object in memory. For example, for one of the objects it returns the following retainers:
From what I can tell, the object is retained because it's used inside a closure scope of a click event. But the click event is on a detached HtmlDivElement, which should be garbage collected. It is somehow linked to the window object via InternalNode objects. I have searched all over the internet, but I'm unable to find what these InternalNode objects are.
My question is, what are these InternalNode objects and how I can "free" them so my objects are garbage collected.
I am diagnosing a memory leak in a jQuery based single page application using the Chrome DevTools heap snapshot tool as described on https://developer.chrome./docs/devtools/memory-problems/#discover_detached_dom_tree_memory_leaks_with_heap_snapshots
I have solved some issues this way, but I have now hit a roadblock where I can no longer determine what is keeping an object in memory. For example, for one of the objects it returns the following retainers:
From what I can tell, the object is retained because it's used inside a closure scope of a click event. But the click event is on a detached HtmlDivElement, which should be garbage collected. It is somehow linked to the window object via InternalNode objects. I have searched all over the internet, but I'm unable to find what these InternalNode objects are.
My question is, what are these InternalNode objects and how I can "free" them so my objects are garbage collected.
Share edited Mar 29, 2021 at 19:15 Wazner asked Mar 25, 2021 at 14:56 WaznerWazner 3,1121 gold badge21 silver badges26 bronze badges 7- See this ment in the source code. – woxxom Commented Mar 25, 2021 at 15:05
- @wOxxOm Thanks. I see there is a preprocessor symbol to turn off the "InternalNode" name hiding. I'll try if I can built chromium with that flag and check the heap profile again. – Wazner Commented Mar 25, 2021 at 16:49
- @wOxxOm I revealed the names of the InternalNode entries. The detached element is being kept alive by blink::MouseEventManager. I'll have to dive deeper, but it might be a chromium bug.. – Wazner Commented Mar 29, 2021 at 18:58
- 1 Probably crbug./1177010 – woxxom Commented Mar 29, 2021 at 18:59
- @wOxxOm Damn. You're right! Clicking on an element outside the element being detached prevents the object leak. Could you post that as an answer, so I can accept it? – Wazner Commented Mar 29, 2021 at 19:10
2 Answers
Reset to default 5There have been some changes in this space in the last couple of years. As of November 2023, these steps will get you useful names instead of "InternalNode".
- Download Chrome for Testing, or build your own Chromium with the GN build flag
cppgc_enable_object_names = true
. - In the developer tools, in Settings, under Experiments, check the box entitled "Show option to expose internals in heap snapshots".
- In the developer tools, in the Memory tab, check the box entitled "Expose internals (includes additional implementation-specific details)".
- Take a heap snapshot.
TL;DR
Leak is caused by https://crbug./1177010
Clicking on an element outside the detached element prevents the memory leak from occuring.
Following @wOxxOm's ment, I have piled a version of Chromium with the enable_additional_blink_object_names
flag enabled so that it shows the names of the InternalNode
objects.
It appears blink:MouseEventManager
is preventing the detached dom element from being garbage collected.
This finally lead me to https://crbug./1177010, which I could confirm by clicking outside the detached element before taking another heap snapshot.