{"id":23495213,"url":"https://github.com/willklein/memory-leaks-notes","last_synced_at":"2026-01-22T13:47:51.568Z","repository":{"id":145188886,"uuid":"292076417","full_name":"willklein/memory-leaks-notes","owner":"willklein","description":null,"archived":false,"fork":false,"pushed_at":"2020-09-01T20:17:43.000Z","size":5,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-19T02:13:50.227Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willklein.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-01T18:27:31.000Z","updated_at":"2023-03-07T13:34:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"9858b09f-6329-4b49-8512-af7a2c318833","html_url":"https://github.com/willklein/memory-leaks-notes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/willklein/memory-leaks-notes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willklein%2Fmemory-leaks-notes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willklein%2Fmemory-leaks-notes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willklein%2Fmemory-leaks-notes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willklein%2Fmemory-leaks-notes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willklein","download_url":"https://codeload.github.com/willklein/memory-leaks-notes/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willklein%2Fmemory-leaks-notes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28663976,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-25T03:14:42.048Z","updated_at":"2026-01-22T13:47:51.551Z","avatar_url":"https://github.com/willklein.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Memory Leaks and the Havoc They Wreak\n\n## Presentation\n\nVideo: coming soon  \nSlides: coming soon\n\n## Notes\n\nConfused about Stack and Heap? by Franziska Hinkelmann: https://medium.com/fhinkel/confused-about-stack-and-heap-2cf3e6adb771\n\nJavaScript primitives: https://developer.mozilla.org/en-US/docs/Glossary/Primitive\n\nJavaScript objects (stuff that leaks): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Objects\n\nMaximum call stack size exceeded example: https://github.com/christianalfoni/formsy-react/issues/298\n\n### Debugging examples\n\nFor the first one, the code is really immaterial.\n\nThe second one involves a crazy closure that just grows memory usage until disaster:\n\n```\n  var run = function () {\n    var str = new Array(1_000_000).join('*');\n\n    var doSomethingWithStr = function () {\n      if (str === 'something')\n        console.log(\"str was something\");\n    };\n\n    doSomethingWithStr();\n\n    var logIt = function () {\n      console.log('interval');\n    }\n\n    setInterval(logIt, 100);\n  };\n\n  setInterval(run, 1000);\n```\n\nDavid Glasser's article: http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html\n\n\n### Patterns and Pitfalls\n\nGlobals\n\n```javascript\nglobalVar = something;\n\nwindow.coolThing = somethingBetter;\n\n```\nEvents \u0026 Callbacks\n\n```javascript\ndocument.addEventListener('click', clickHandler)\n\n// sometime later\ndocument.removeEventListener('click', clickHandler)\n\n```\n\nMistakes, GitHub PR example with adding listeners twice: https://github.com/mattermost/mattermost-webapp/pull/585/files#diff-80a46c6ad8edb475be6ad3d466cf92c2\n\n\nCaching example (lru-cache):\n```javascript\n// https://www.npmjs.com/package/lru-cache\nvar LRU = require(\"lru-cache\"),\n\nvar cache = new LRU(50) // max size of 50\n\ncache.set(\"MC\", \"Cassidy Williams\")\ncache.get(\"MC\") // \"Cassidy Williams\"\n```\nAsynchronous timing example (setTimeout/setInterval)\n\n```javascript\n// woops, my slide had a copy/paste error\n\nsetTimeout(happensLater, 2000);\n\nfunction happensLater () {\n  // this can go wrong a number of ways\n  // use setTimeout/setInterval, but with care\n}\n```\n\n\nBasic closure, for reference:\n\n```javascript\nvar closureScope = { functions: 'get me' }\n\nfunction getMessage(key) {\n  return closureScope[key]\n}\n```\n\n### performance.measureMemory API\n\nProposal on GitHub: https://github.com/WICG/performance-measure-memory\n\nChrome Platform status: https://www.chromestatus.com/feature/5685965186138112\n\n```javascript\nif (performance.measureMemory) {\n  let result;\n  try {\n    result = await performance.measureMemory(); // this is it\n  } catch (error) {\n    /* ... */\n  }\n\n  // you could send telemetry data to an API\n  console.log(result);\n}\n```\n\nFull quote from Ulan Degenbaev, from https://web.dev/monitor-total-page-memory-usage/\n\n\u003e Browsers manage the memory of web pages automatically. Whenever a web page creates an object, the browser allocates a chunk of memory \"under the hood\" to store the object. Since memory is a finite resource, the browser performs garbage collection to detect when an object is no longer needed and to free the underlying memory chunk. The detection is not perfect though, and it was proven that perfect detection is an impossible task. Therefore browsers approximate the notion of \"an object is needed\" with the notion of \"an object is reachable\". If the web page cannot reach an object via its variables and the fields of other reachable objects, then the browser can safely reclaim the object. The difference between these two notions leads to memory leaks\n\n## Contact\n\nEmail: will@willklein.co  \nTwitter: [@willklein_](https://twitter.com/willklein_) (DM's always open)\n\n### More thoughts\n\nI didn't talk much about backend services, but here's some more thoughts on that\n\n### Site Reliability Engineering\n\nIf you're building services on the backend, look into topics of observability and site reliability engineering. Our dev ops friends can definitely help with this but it’s something you can pick up as you go. For more background, check out the set of Site Reliability Engineering books from the folks at Google and published by O’Reilly here: https://landing.google.com/sre/books/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillklein%2Fmemory-leaks-notes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillklein%2Fmemory-leaks-notes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillklein%2Fmemory-leaks-notes/lists"}