-
Notifications
You must be signed in to change notification settings - Fork 18
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
would like dcmd for heuristically finding back references #107
Comments
I just discovered that mdb has a private function called |
I implemented the behavior I described for At this point, it still needs some cleanup, documentation, and tests. |
I've put up a change for Some notes for reviewers:
I have a copy at the the same GitHub branch as before, so you can see the docs for the new dcmd here: |
PS3 of the above change passes the
|
I've updated the Gerrit CR in response to code review feedback. I'm rerunning the test suite on the same Node versions as before. |
Here are the test results from PS4:
More specifically, across all Node versions, there were two test failures. They both appear to be instances of #38:
(This also looks like #97, but this PS has the fix for that issue.) |
As described in #38, this issue does seem intermittent:
I think this can count as a clean test run. Obviously, we should still fix #38, but I don't think this work should be blocked on that. |
Reviewed by: Cody Peter Mello <[email protected]> Approved by: Cody Peter Mello <[email protected]>
Integrated. Thanks @melloc for the review! |
While debugging issues related to memory usage (including memory leaks), it's common to look at a particular object and want to know what other references exist for that object.
findjsobjects -r
can help with this, though it's extremely time-consuming. (On large core files -- and issues related to memory usage often result in large core files -- each iteration can take tens of minutes, and you often want to make dozens of iterations.) It also doesn't currently find objects referenced via closures -- see #105.In the meantime, I discovered that I could find back references reasonably reliably using a combination of
ugrep
and scouring nearby memory. It basically works like this: I'd find an interesting representative object fromfindjsobjects
and look for references:But using
ugrep
, I'd find that it was referred to elsewhere:Then I'd try to summarize the region of memory ahead of that reference like this:
Observing that virtually every V8 heap object has as its first word a pointer to a
Map
, I'd walk back from my pointer to the first address that points to aMap
. In this case, that's400bc4e08be8
. To get the heap object's address, we have to takeaddr|1
--400bc4e08be9
in this case. Then I'd try to print that out, and sure enough:It's a FixedArray, and our original value is one of its elements:
I used this approach iteratively to reconstruct a tree that included 4 JSObjects, 1 JSArray, 6 closures, and a handful of FixedArrays that were used as intermediate values (e.g., for arrays or closure contexts). It was tedious and time-consuming, especially when it branched (i.e., there was more than one reference), but it was pretty reliable, and it can be done automatically quite quickly.
I'd propose a couple of dcmds like:
which would essentially follow this heuristic:
ugrep
to find candidates addresses.ugrep
is actually contained in the object. Many heap classes are fixed-size, which makes it pretty easy. Others are variable size (like strings, FixedArrays, and JSObjects), but we can tell how big they are from the information in them. This check should eliminate many false positives.v8findrefs
, we're done -- report the reference and move onto the nextugrep
candidate.jsfindrefs
, we could do a little more interpretation: if we find a FixedArray, we should probably take the next step and find where that FixedArray is referenced. It's likely to be a closure or a JSArray.I'm envisioning that
v8findrefs
would iterate just once and report the V8 heap objects that immediately refer to the given address, whilejsfindrefs
would keep following each path until it finds the next JS-level object along each path. Either of these could take an option to repeat the process a number of times.As for an appropriate default for
SIZE
: the maximum you'd have to walk back for fixed-size objects is the size of the largest fixed-size object that we know about. Fortunately, we have that information. For strings and arrays, you might have to walk back arbitrarily further than that, since those are arbitrary-sized objects. But since we can always stop when we find the firstMap
, and false positives can usually be eliminated with the check above, there's no reason not to set this limit fairly high (e.g., even a few hundred KB).Although this was mostly useful here because we don't yet have #105, and the performance issues associated with
findjsobjects -r
could also be addressed with the export-to-sqlite path, I think these dcmds would still be useful tools to have.I will add a detailed analysis for the original problem to MORAY-455, in case that's helpful.
The text was updated successfully, but these errors were encountered: