-
Notifications
You must be signed in to change notification settings - Fork 130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: Any idea about ignoring weak reference and circular reference in heap snapshot? #106
Comments
@LZTWilliam I just double checked the code, I've excluded weakMap references to key (totally forgot it since it was added a while ago). The edge you got is actually a WeakMap pointing to the value part of the key-value pair (i.e., it points to object
So you might want to use this command to figure out why the key object
|
@JacksonGL Thanks for your reply! You correct a long-term misunderstanding for me.
It does make sense since the value (JSProxy @2480815) is a proxy created by key (Object @2516105). But will this lead to the result that the key will never be gc'd? Or there must be other codes in the framework to release the reference manually. In addition, the key (Object @2516105) is only referenced by JSProxy @2480815. So I'm planning to find out what's happening in the framework and the lifecycle management of entries in that WeakMap. Thanks again! |
Yes
@LZTWilliam I believe V8 should be smart enough to GC both key and value if 1) the only strong reference to the key comes from the value, and 2) there is no other strong references keeping the value alive. Actually you can check with a small test case in Chrome's web console and V8 can indeed release both key and value if value points to key: let map = new WeakMap();
let arr= [{}, {}];
arr[1].ref = arr[0];
map.set(arr[0], arr[1]);
// take a heap snapshot and see that
// the WeakMap contains the key/value pair
// --------------
arr = [];
console.clear();
// take another heap snapshot and
// now the WeakMap does not contain the key/value pair It might be possible that in your case the key (object |
I've checked the retain chain on several objects. I believe there's no such k/v pairs chain.
@JacksonGL Definitely! This is why I'm looking for other powerful tools. Am I able to ignore all references from WeakMap(Under the assumption of no k/v pairs chain and key referenced by its value can be gc'd by V8) in memlab? It's way too complicated to find the "ultimately" manually in my heap snapshot. Most of the retain chain finally lead to WeakMap. Is it possible to read the snapshot file, modify edges and nodes by IHeapSnaphost interface, and save it to another file? Update: hacked this function and call |
@LZTWilliam if that's the case you might want to check if there is other referrers / retainers keeping either the key or the value alive (please check out my earlier comment on how to do that).
Yes, looks like you already had the code change (in your screenshot) to achieve this.
MemLab currently does not support modifying or serializing heap snapshots. |
Ignoring all WeakMap edge is very useful in my case. Found a self-written leak point and a third-party component leak point My best practice is:
Considering the complexity of reference chain in javascript(especially with framework), an IEdgeFilter interface might be useful, providing an official way to ignore certain kind of references. Anyway, thanks again for all the replies! |
Summary: This diff adds a new callback that can be used to define a logic to decide whether a reference should be considered as part of the retainer trace. The callback is called for every reference (edge) in the heap snapshot. The callback accepts the following parameters * `edge` - the reference (edge) that is considered for calcualting the retainer trace * `snapshot` - the snapshot of target interaction * `isReferenceUsedByDefault` - MemLab has its own default logic for whether a reference should be considered as part of the retainer trace, if this parameter is true, it means MemLab will consider this reference when calculating the retainer trace. The return value indicates whether the given reference should be considered when calculating the retainer trace. Note that when this callback returns true, the reference will only be considered as a candidate for retainer trace, so it may or may not be included in the retainer trace; however, if this callback returns false, the reference will be excluded. Note that by excluding a dominator reference of an object (i.e., an edge that must be traveled through to reach the heap object from GC roots), the object will be considered as unreachable in the heap graph; and therefore, the reference and heap object will not be included in the retainer trace detection and retainer size calculation. ``` // save as leak-filter.js module.exports = { retainerReferenceFilter(edge, _snapshot, _leakedNodeIds) { // exclude react fiber references if (edge.name_or_index.toString().startsWith('__reactFiber$')) { return false; } return true; } }; ``` Use the leak filter definition in command line interface: ``` memlab find-leaks --leak-filter <PATH TO leak-filter.js> ``` ``` memlab run --scenario <SCENARIO FILE> --leak-filter <PATH TO leak-filter.js> ``` Differential Revision: D53167155 fbshipit-source-id: b9006fd309276452acbe216c577f34c28b071ffa
I've been locating memory leak problem for days. Memory tool in Chrome DevTools is good, but in my case, not enough.
The framework (Vue3 BTW) creates a WeakMap and store it in a global handle, stores a mapping from object to its proxy. And the map will never be gc'd (by design).
When I start locating the leak point, almost every object is referenced as a key by this WeakMap. And in my opinion, this is a weak reference, which shouldn't prevent object from being gc'd. So I just want the tool to ignore these weak references.
I also found chromium issue requiring this feature, unfortunately it has been closed for several years.
https://bugs.chromium.org/p/chromium/issues/detail?id=1103770
And finally I found memlab, after using "memlab find-leaks" to analyze heap snapshot, I found this. WeakMap still on every reference chain of leaks.
The leak point shall be found by locating the objects that have strong reference on [Object] (object) @2516105 [688 bytes]
Would you mind providing advices about this feature? Or is there other ways to achieve this? Sincerely appreciates.
The text was updated successfully, but these errors were encountered: