HeapViz is a Chrome heap profile visualization tool. It helps to diagnose memory leaks, memory allocation issues, and large in-memory objects.
You can find a hosted version at heapviz.com.
- Generate a heap allocation profile
- Upload your profile to heapviz, either at heapviz.com or locally
- Wait for the profile to parse and render. This can take some time, especially for large profiles.
- Step through your profile with arrow keys. Click and drag the timeline to create a selection region. Click on individual circles for detailed information about edges and retainers.
For a detailed walkthrough both of the development of HeapViz and a quick guide on using the tool, see my six part article series.
- Intuition Engineering and the Chrome Heap Profile
- Choosing a Visualization Method
- Renderers in all Shapes and Sizes
- Working with Workers for a Jank-Free UI
- Screamin' Speed With WebAssembly
- Introducing HeapViz
To build and run HeapViz yourself:
- Clone the repo
- Ensure you have
node
andyarn
(ornpm
) installed yarn
yarn start
For a production build, use yarn build
.
Included is also a Dockerfile if you prefer that
HeapViz was created with Create React App, check out those docs for some hints on directory structure.
HeapViz has a few moving parts
- React frontend, Redux store, Redux-Observable for side-effects.
- Webpack 1.4 build system
- TypeScript for types
- The heap profile parsing is done in a worker (
src/services/worker
) with the profile parsing code forked from Chromium - the source has since moved on, but you can get a sense of what it looks like in context here - We also do our circle layout in the worker. I've transcribed d3-heirarchy's circle packing algorithm to C++ and compiled it to WebAssembly (see
public/pack-circles
). - One of the biggest performance wins would be to incorporate the feedback by doom_Oo7 to refine the circle packing algorithm.
- We could also hook up the WebAssembly loader to save some bytes in the WebAssembly loading (currently using emscripten's default loading code which is pretty weighty )
- Rendering is done by
src/services/renderer
, using StackGL packages to wrap WebGL primitives. As noted in this tweet, there is a quick win to be had in the rendering pipeline. - I'm pretty proud of my object picking code - see
src/services/renderer/picker.ts
. I basically create a second rendering, except each circle in this rendering is a unique color. I then hold a map of these unique colors to their respective nodes and use gl.readPixels to look up the appropriate node. - We do some really basic caching of each render to ensure that we don't have to re-layout whenever we have the same set of filtered nodes. This is a big performance win but majorly spikes memory usage, especially when stepping through large memory profiles. Having a way to disable the cache would be a good idea.
HeapViz is released under the Apache license. I'd appreciate attribution if you use it out in the wild.
PR's welcome, I'd love to work with people to turn this into a really useful tool.
- Travis build
- Circle-pack improvements
- Rendering improvements
- Move parsing, layout, and rendering to separate packages
- Clean up - there are a few extra files and dependencies that need to be purged
- Write some tests
- Find more intuitive ways to filter to more easily expose problem objects
If you're really awesome and think I should keep doing this with my spare time, feel free to throw me a few bucks on Patreon or if you prefer crypto, I'm at
- BTC: 38Le1nkuYWeM24zUi1doCKdgVmJdSA9TbL
- ETH: 0x441C6BEEf42A5506FC7bb1Cec28c31370f69Ba19
- BCH: qqa8777f0w5fl2vhuf4cdwjn66slwtm00vrzmzxhuf