Analysis of Memory leakage in Node. js, analysis of node. js

Source: Internet
Author: User

Analysis of Memory leakage in Node. js, analysis of node. js

This article is the first article in the Node. JS Holiday Season series by Mozilla's Identity team. The team released the first beta version of Persona last month. When developing Persona, we built a series of tools, including debugging, localization, dependency management, and more. In this series of articles, we will share our experiences and tools with the community, which is useful to anyone who wants to build a high availability service with node. js. We hope you will like these articles and look forward to seeing your thoughts and contributions.

We will start with a topic article about Node. js: Memory leakage. We will introduce node-memwatch-a function library that helps detect and isolate memory leaks in nodes.


Why are you worried?

The most frequently asked question about tracing memory leaks is, "Why bother ?". Is there no more urgent problem to be solved first? Why not choose to restart the service from time to time or allocate more RAM to it? To answer these questions, we provide the following three suggestions:

1. You may not care about the increasing memory usage, but V8 (V8 is the Node runtime engine ). As memory leakage increases, V8 becomes more and more aggressive with the garbage collector, which slows down the running of your application. Therefore, on the Node, memory leakage will damage program performance.

2. Memory leakage may trigger other types of failures. Memory leakage code may continuously reference limited resources. You may run out of file descriptors, and suddenly you cannot create new database connections. This type of problem may be exposed long before your application runs out of memory, but it will still be difficult for you.

3. At last, your application will crash sooner or later, and it will certainly happen when your application is popular. Everyone will laugh at you on Hacker News and Satirize you, so that you will suffer.

Where is the ant nest that breaks the treasure of a thousand miles?

Memory leakage may occur in many places when building complex applications. Closures may be the most widely known and notorious. Because the closure retains the reference to something in its scope, which is the source of Memory leakage.

Closure leaks are often discovered only when someone looks for them. However, in the asynchronous world of Node, we continuously generate closures through callback functions anytime and anywhere. If these callback functions are not used immediately after creation, the allocated memory will continue to grow and the code that seems to have no memory leakage problems will also be leaked. This problem is more difficult to find.

Your application may also cause memory leakage due to upstream code problems. Maybe you can locate the Code with Memory leakage, but you may have to stare at your perfect code and then get confused about how the code is leaked!


It is these hard-to-locate memory leaks that make us want a tool like node-memwatch. It is said that a few months ago, our Lloyd Hilaiel locked himself in a small room for two days and tried to track a memory leak that became very obvious under stress testing. (By The Way, please look forward to the upcoming articles about the load testing by Lloyd)

After two days of hard work, he finally found the culprit in the Node kernel: The Event listener in http. ClientRequest was not released. (The patch that finally fixes this problem has only two but crucial letters ). This painful experience prompted Lloyd to write a tool that can help find memory leaks.

Memory Leak locating Tool

There are already many easy-to-use and constantly enhanced tools to locate the memory leakage of Node. js applications. Below are some of them:

  • Jimb Esser's node-mtrace, which uses the GCC mtrace tool to analyze the usage of the heap.
  • Dave Pacheco's node-heap-dump captures a snapshot of the V8 heap and serializes everything into a huge JSON file. It also contains some JavaScript tools that analyze the snapshot results.
  • Danny Coates's v8-profiler and node-inspector provide a V8 analyzer bound to Node and a debug Interface Based on WebKit Web Inspector.
  • The chart branch of the Felix Gnass is not disabled.
  • Felix Geisendorfer's Node Memory Leak Guide (Node Memory Leak Tutorial) is a short and cool v8-profiler and node-debugger usage Tutorial. It is also the most advanced Node. js Memory Leak debugging technical guide.
  • Joyent's SmartOS platform provides a large number of tools for debugging Node. js memory leaks.

We all like the above tools, but none of them are applicable to our scenarios. Web Inspector is great for developing applications, but it is difficult to use in hot deployment scenarios, especially when multiple servers and sub-processes are involved. Similarly, memory leaks that occur during long high-load operations are hard to reproduce. Tools such as dtrace and libumem are impressive, but not all operating systems can use them.

Enternode-memwatch

We need a cross-platform debugging library. When the memory of our program may leak, it does not need to be told by the device and will help us find the leak. So we implemented node-memwatch.

It provides us with three things:

A 'leakage' event Transmitter

   memwatch.on('leak', function(info) {  // look at info to find out about what might be leaking  });

A 'status event Transmitter


  var memwatch = require('memwatch');  memwatch.on('stats', function(stats) {  // do something with post-gc memory usage stats  });

Classification of one heap memory Zone

  var hd = new memwatch.HeapDiff();  // your code here ...  var diff = hd.end();

In addition, it is useful in testing and can trigger the Garbage Collector function. Okay, there are four points in total.

 var stats = memwatch.gc();

Memwatch. on ('stats',...): Post-GC heap statistics

Node-memwatch can produce a memory usage sample immediately after a complete garbage collection and memory compression before any JS object is allocated. (It uses the V8 post-gc hook, V8: AddGCEpilogueCallback, to collect heap usage information every time garbage collection is triggered)

Statistics include:

  • Usage_trend (usage trend)
  • Current_base (current base)
  • Estimated_base (expected Base)
  • Num_full_gc (total garbage collection times)
  • Num_inc_gc (increase in the number of garbage collection times)
  • Heap_compactions (memory compression times)
  • Min (min)
  • Max (max)

Here is an example of how the data of an application with Memory leakage looks like. The following chart tracks memory usage over time. The crazy green line shows the content of the process. memoryUsage () report. The red line shows the current_base of the node_memwatch report. The lower-left box shows additional information.

Note that the Incr GCs is very high. That means V8 is desperately trying to clean up the memory.

Memwatch. on ('leak',...): heap distribution trend

We have defined a simple detection algorithm to remind you that your application may have memory leaks. That is, if the memory is continuously allocated and not released after five consecutive GC operations, node-memwatch will issue a leak event. The specific event information format is clear and easy to read, as shown in the following figure:
 

{ start: Fri, 29 Jun 2012 14:12:13 GMT, end: Fri, 29 Jun 2012 14:12:33 GMT, growth: 67984, reason: 'heap growth over 5 consecutive GCs (20s) - 11.67 mb/hr' }

Memwatch. HeapDiff (): Find leakage culprit

Finally, node-memwatch can compare the names of objects on the stack with the number of snapshots allocated. The differences between the two can help identify the culprit that causes memory leakage.
 

var hd = new memwatch.HeapDiff(); // Your code here ... var diff = hd.end();

The comparison results are as follows:
 

{ "before": {  "nodes": 11625,  "size_bytes": 1869904,  "size": "1.78 mb" }, "after": {  "nodes": 21435,  "size_bytes": 2119136,  "size": "2.02 mb" }, "change": {  "size_bytes": 249232,  "size": "243.39 kb",  "freed_nodes": 197,  "allocated_nodes": 10007,  "details": [   {    "what": "Array",    "size_bytes": 66688,    "size": "65.13 kb",    "+": 4,    "-": 78   },   {    "what": "Code",    "size_bytes": -55296,    "size": "-54 kb",    "+": 1,    "-": 57   },   {    "what": "LeakingClass",    "size_bytes": 239952,    "size": "234.33 kb",    "+": 9998,    "-": 0   },   {    "what": "String",    "size_bytes": -2120,    "size": "-2.07 kb",    "+": 3,    "-": 62   }  ] }}

The HeapDiff method performs a complete garbage collection before sampling data, so that the obtained data is not filled with too much useless information. Memwatch event processing ignores the garbage collection events triggered by HeapDiff. Therefore, you can safely call the HeapDiff method in the listener callback function of the stats event.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.