frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

Open in hackernews

Helpful function to find memory leaks in JavaScript

3•EGreg•3d ago
I had a tough time understanding where memory leaks are coming from, especially on iOS safari. I'd go into Dev Tools > Timelines tab and see the memory go up, but not sure how or where. So I wrote this function to traverse all the global objects that have been added by various software, avoiding revisiting the same objects more than once. The function is async so as not to tie up the UX too much. You can run it to start seeing where the references are being leaked.

  Q = {};

  Q.globalNames = Object.keys(window); // snapshot baseline

  Q.globalNamesAdded = function () {
   const current = Object.keys(window);
   const baseline = Q.globalNames;
   const added = [];
  
   for (let i = 0; i < current.length; i++) {
    if (!baseline.includes(current[i])) {
     added.push(current[i]);
    }
   }
   return added;
  };
  
  Q.walkGlobalsAsync = function (filterFn, options = {}) {
    const seen = new WeakSet();
    const found = new Set();
    const pathMap = new WeakMap();

    const maxDepth = options.maxDepth || 5;
    const includeStack = options.includeStack || false;
    const logEvery = options.logEvery || 100;
    const startingKeys = Q.globalNamesAdded
      ? Q.globalNamesAdded()
      : Object.keys(window);

    let totalChecked = 0;
    let matchesFound = 0;

    function walk(obj, path = 'window', depth = 0) {
      if (!obj || typeof obj !== 'object') return;
      if (seen.has(obj)) return;
      seen.add(obj);

      totalChecked++;
      if (totalChecked % logEvery === 0) {
        console.log(`Checked ${totalChecked} objects, found ${matchesFound}`);
      }

      if (filterFn(obj)) {
        found.add(obj);
        matchesFound++;
        if (includeStack) {
          pathMap.set(obj, path);
          console.log(`[FOUND] ${path}`, obj);
        } else {
          console.log(`[FOUND]`, obj);
        }
      }

      if (depth >= maxDepth) return;

      const skipKeys = obj instanceof HTMLElement
        ? new Set([
            'parentNode', 'parentElement', 'nextSibling', 'previousSibling',
            'firstChild', 'lastChild', 'children', 'childNodes',
            'ownerDocument', 'style', 'classList', 'dataset',
            'attributes', 'innerHTML', 'outerHTML',
            'nextElementSibling', 'previousElementSibling'
          ])
        : null;

      for (const key in obj) {
        if (skipKeys && skipKeys.has(key)) continue;
        try {
          walk(obj[key], path + '.' + key, depth + 1);
        } catch (e) {}
      }
    }

    let i = 0;
    function nextBatch() {
      const batchSize = 10;
      const end = Math.min(i + batchSize, startingKeys.length);

      for (; i < end; i++) {
        try {
          walk(window[startingKeys[i]], 'window.' + startingKeys[i], 0);
        } catch (e) {}
      }

      if (i < startingKeys.length) {
        setTimeout(nextBatch, 0); // Schedule next batch
      } else {
        console.log(`Done. Found ${matchesFound} retained objects.`);
        if (includeStack) {
          console.log([...found].map(obj => ({
            object: obj,
            path: pathMap.get(obj)
          })));
        } else {
          console.log([...found]);
        }
      }
    }

    nextBatch();
  };
Here is how you use it:

  Q.walkGlobalsAsync(
   obj => obj instanceof HTMLElement && !document.contains(obj),
   { includeStack: true, maxDepth: 4, logEvery: 50 }
  );
However -- note that this will NOT find objects retained by closures, even if you can find the closures themselves you're going to have to check their code manually.

Comments

NoahZuniga•1d ago
Chrome has a great memory profiler, which can give you this information and more.

Ask HN: Where are the AI-driven profits or promotions?

30•arduinomancer•9h ago•33 comments

Ask HN: How are you productively using Claude code?

7•nocobot•5h ago•5 comments

Ask HN: How did Soham Parekh get so many jobs?

314•jshchnz•1w ago•415 comments

Ask HN: How do you get first 10 customers?

8•jcofai•18h ago•10 comments

Ask HN: Has anybody gotten a Node.js MCP server to work with HTTP?

2•rglover•12h ago•2 comments

Ask HN: Are there any tools for tracking GPU prices over time?

2•jepeake•16h ago•2 comments

Attended Windsurf's Build Night 18 hours before founders joined Google DeepMind

5•schwentkerr•1d ago•0 comments

Ask HN: Looking for a directory of PS1 command prompts. Like awesome lists

2•simplecto•1d ago•2 comments

Tell HN: I Lost Joy of Programming

91•Eatcats•5d ago•124 comments

Co-founder exiting after pivot – what's a fair exit package?

42•throwaway-xx•4d ago•78 comments

Ask HN: Bug Bounty Dilemma – Take the $$ and Sign an NDA or Go Public?

22•deep_thinker26•4d ago•14 comments

Helpful function to find memory leaks in JavaScript

3•EGreg•3d ago•1 comments

Ask HN: Worth leaving position over push to adopt vibe coding?

80•NotAnOtter•1w ago•94 comments

Ask HN: People who work different timezones than your company. How sched?

17•tetris11•4d ago•27 comments

Ask HN: What do you do with your list of articles links?

4•electricant•1d ago•10 comments

Ask HN: How to Create Data Flow Diagrams?

4•shivajikobardan•2d ago•2 comments

Ask HN: Good non tech companies to work at

4•nzmkk•2d ago•12 comments

Tell HN: uBlock Origin on Chrome is finally gone

160•ipsum2•1d ago•150 comments

Ask HN: What techniques do you use to remember complex concepts and theories?

5•anonymzz•2d ago•4 comments

The computational cost of corporate rebranding

4•rileygersh•2d ago•0 comments

Ask HN: Does your on-call rotation suck? Can I join it?

11•asciifree•4d ago•23 comments

Ask HN: What's the verdict on GPT wrapper companies these days?

15•NewUser76312•5d ago•18 comments

Google fails to dismiss wiretapping claims on SJ, settles with app users

43•1vuio0pswjnm7•3d ago•8 comments

Ask HN: How can I invest in Solar Power?

4•idontwantthis•2d ago•10 comments

Ask HN: Any resources for finding non-smart appliances?

156•everyone•6d ago•132 comments

I built a AI transcription app because my girlfriend needed one for uni

4•ebukao•2d ago•9 comments