![Screenshot 2019-12-16 10 51 05](https://user-images.githubusercontent.com/793565/70934095-fd91ed80-1ff1-11ea-93b5-746e816585ec.png)
There's seems to be circumstances where unmounted DOM/Fibers are kept alive by React DevTools. They're kept alive in `primaryFibers`:
https://github.com/facebook/react/blob/34527063083195558f98108cde10b5d6ad0d6865/packages/react-devtools-shared/src/backend/renderer.js#L772

It seems like a WeakSet would be appropriate and would remove the leak. Otherwise we'd need to understand why recordUnmount isn't called.

CC @bvaughn  
const idToTreeBaseDurationMap: Map<number, number> = new Map();
   When profiling is supported, we store the latest tree base durations for each Fiber.
   This map enables us to filter these times by root when sending them to the frontend.
  const idToRootMap: Map<number, number> = new Map();
   When a mount or update is in progress, this value tracks the root that is being operated on.
  let currentRootID: number = -1;
   Returns the unique ID for a Fiber or generates and caches a new one if the Fiber hasn't been seen before.
   Once this method has been called for a Fiber, untrackFiberID() should always be called later to avoid leaking.
  function getOrGenerateFiberID(fiber: Fiber): number {
    let id = null;
    if (fiberToIDMap.has(fiber)) {
      id = fiberToIDMap.get(fiber);
    } else {
      const {alternate} = fiber;
      if (alternate !== null && fiberToIDMap.has(alternate)) {
        id = fiberToIDMap.get(alternate);
      }
    }
    let didGenerateID = false;
    if (id === null) {
      didGenerateID = true;
      id = getUID();
    }
     This refinement is for Flow purposes only.
    const refinedID = ((id: any): number);
     Make sure we're tracking this Fiber
     e.g. if it just mounted or an error was logged during initial render.
    if (!fiberToIDMap.has(fiber)) {
      fiberToIDMap.set(fiber, refinedID);
      idToArbitraryFiberMap.set(refinedID, fiber);