{"id":13511555,"url":"https://github.com/lloyd/node-memwatch","last_synced_at":"2025-05-13T21:11:01.744Z","repository":{"id":2411623,"uuid":"3379489","full_name":"lloyd/node-memwatch","owner":"lloyd","description":"A NodeJS library to keep an eye on your memory usage, and discover and isolate leaks.","archived":false,"fork":false,"pushed_at":"2022-12-29T17:24:55.000Z","size":433,"stargazers_count":2510,"open_issues_count":56,"forks_count":299,"subscribers_count":52,"default_branch":"master","last_synced_at":"2025-04-28T17:02:41.319Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lloyd.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-02-07T17:15:52.000Z","updated_at":"2025-04-10T00:48:35.000Z","dependencies_parsed_at":"2023-01-13T11:50:30.922Z","dependency_job_id":null,"html_url":"https://github.com/lloyd/node-memwatch","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lloyd%2Fnode-memwatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lloyd%2Fnode-memwatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lloyd%2Fnode-memwatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lloyd%2Fnode-memwatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lloyd","download_url":"https://codeload.github.com/lloyd/node-memwatch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254029002,"owners_count":22002283,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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-08-01T03:00:55.801Z","updated_at":"2025-05-13T21:10:56.733Z","avatar_url":"https://github.com/lloyd.png","language":"C++","readme":"`node-memwatch`: Leak Detection and Heap Diffing for Node.JS\n============================================================\n\n[![Build Status](https://secure.travis-ci.org/lloyd/node-memwatch.png)](http://travis-ci.org/lloyd/node-memwatch)\n\n`node-memwatch` is here to help you detect and find memory leaks in\nNode.JS code.  It provides:\n\n- A `leak` event, emitted when it appears your code is leaking memory.\n\n- A `stats` event, emitted occasionally, giving you\n  data describing your heap usage and trends over time.\n\n- A `HeapDiff` class that lets you compare the state of your heap between\n  two points in time, telling you what has been allocated, and what\n  has been released.\n\n\nInstallation\n------------\n\n- `npm install memwatch`\n\nor\n\n- `git clone git://github.com/lloyd/node-memwatch.git`\n\n\nDescription\n-----------\n\nThere are a growing number of tools for debugging and profiling memory\nusage in Node.JS applications, but there is still a need for a\nplatform-independent native module that requires no special\ninstrumentation.  This module attempts to satisfy that need.\n\nTo get started, import `node-memwatch` like so:\n\n```javascript\nvar memwatch = require('memwatch');\n```\n\n### Leak Detection\n\nYou can then subscribe to `leak` events.  A `leak` event will be\nemitted when your heap usage has increased for five consecutive\ngarbage collections:\n\n```javascript\nmemwatch.on('leak', function(info) { ... });\n```\n\nThe `info` object will look something like:\n\n```javascript\n{ start: Fri, 29 Jun 2012 14:12:13 GMT,\n  end: Fri, 29 Jun 2012 14:12:33 GMT,\n  growth: 67984,\n  reason: 'heap growth over 5 consecutive GCs (20s) - 11.67 mb/hr' }\n```\n\n\n### Heap Usage\n\nThe best way to evaluate your memory footprint is to look at heap\nusage right aver V8 performs garbage collection.  `memwatch` does\nexactly this - it checks heap usage only after GC to give you a stable\nbaseline of your actual memory usage.\n\nWhen V8 performs a garbage collection (technically, we're talking\nabout a full GC with heap compaction), `memwatch` will emit a `stats`\nevent.\n\n```javascript\nmemwatch.on('stats', function(stats) { ... });\n```\n\nThe `stats` data will look something like this:\n\n```javascript\n{\n  \"num_full_gc\": 17,\n  \"num_inc_gc\": 8,\n  \"heap_compactions\": 8,\n  \"estimated_base\": 2592568,\n  \"current_base\": 2592568,\n  \"min\": 2499912,\n  \"max\": 2592568,\n  \"usage_trend\": 0\n}\n```\n\n`estimated_base` and `usage_trend` are tracked over time.  If usage\ntrend is consistently positive, it indicates that your base heap size\nis continuously growing and you might have a leak.\n\nV8 has its own idea of when it's best to perform a GC, and under a\nheavy load, it may defer this action for some time.  To aid in\nspeedier debugging, `memwatch` provides a `gc()` method to force V8 to\ndo a full GC and heap compaction.\n\n\n### Heap Diffing\n\nSo far we have seen how `memwatch` can aid in leak detection.  For\nleak isolation, it provides a `HeapDiff` class that takes two snapshots\nand computes a diff between them.  For example:\n\n```javascript\n// Take first snapshot\nvar hd = new memwatch.HeapDiff();\n\n// do some things ...\n\n// Take the second snapshot and compute the diff\nvar diff = hd.end();\n```\n\nThe contents of `diff` will look something like:\n\n```javascript\n{\n  \"before\": { \"nodes\": 11625, \"size_bytes\": 1869904, \"size\": \"1.78 mb\" },\n  \"after\":  { \"nodes\": 21435, \"size_bytes\": 2119136, \"size\": \"2.02 mb\" },\n  \"change\": { \"size_bytes\": 249232, \"size\": \"243.39 kb\", \"freed_nodes\": 197,\n    \"allocated_nodes\": 10007,\n    \"details\": [\n      { \"what\": \"String\",\n        \"size_bytes\": -2120,  \"size\": \"-2.07 kb\",  \"+\": 3,    \"-\": 62\n      },\n      { \"what\": \"Array\",\n        \"size_bytes\": 66687,  \"size\": \"65.13 kb\",  \"+\": 4,    \"-\": 78\n      },\n      { \"what\": \"LeakingClass\",\n        \"size_bytes\": 239952, \"size\": \"234.33 kb\", \"+\": 9998, \"-\": 0\n      }\n    ]\n  }\n```\n\nThe diff shows that during the sample period, the total number of\nallocated `String` and `Array` classes decreased, but `Leaking Class`\ngrew by 9998 allocations.  Hmmm.\n\nYou can use `HeapDiff` in your `on('stats')` callback; even though it\ntakes a memory snapshot, which triggers a V8 GC, it will not trigger\nthe `stats` event itself.  Because that would be silly.\n\n\nFuture Work\n-----------\n\nPlease see the Issues to share suggestions and contribute!\n\n\nLicense\n-------\n\nhttp://wtfpl.org\n","funding_links":[],"categories":["C++","Debugging","目录"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flloyd%2Fnode-memwatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flloyd%2Fnode-memwatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flloyd%2Fnode-memwatch/lists"}