Node.js performance and memory leaks - javascript

I faced some node.js memory weirdness, with react prerendering app. Here is memory profiling via newrelic:
As you can see – once in an hour GC is freeing memory, when it comes up to 1GB. Is this okay for node.js (v0.12.x) or is something going wrong?
P.S. I read about newrelic's memory leaks, but turning it off provides the same results.

It is not nodeJS, it is v8 JS engine.
As far as I know, by #perfmatters talks, these issues (memory/performance) related to javascript can be made better by writing the application which takes more care while allocating new objects.
Here are some useful resource
Youtube: talk by colt McAnlis
Node.js Performance Tip: Managing Garbage Collection

In my experience this looks normal. Without further investigating you'd expect rather short lived, more extreme peaks if it would have been memory leeks. Maybe read up on this here

Related

Node.js and fragmentation

Background: I came from Microsoft world, in which I used to have websites stored on IIS. Experience taught me to recycle my application pool once a day in order to eliminate weird problems due to fragmentation. Recycling the app pool basically means to restart your application without restarting the entire IIS. I also watched a lecture that explained how Microsoft had reduced the fragmentation a lot in .Net 4.5.
Now, I'm deploying a Node.js application to production environment and I have to make sure that it works flawlessly all the time. I originally thought to make my app restarted once a day. Then I did some research in order to find some clues about fragmentation problems in Node.js. The only thing I've found is a scrap of paragraph from an article describing GC in V8:
To ensure fast object allocation, short garbage collection pauses, and
the “no memory fragmentation V8” employs a stop-the-world,
generational, accurate, garbage collector.
This statement is really not enough for me to give up building a restart mechanism for my app, but on the other hand I don't want to do some work if there is no problem.
So my quesion is:
Should or shouldn't I restart my app every now and then in order to prevent fragmentation?
Implementing a server restart before you know that memory consumption is indeed a problem is a premature optimization. As such, I don't think you should do it until you actually find that it is a problem. You will likely find more important issues to optimize for as opposed to memory consumption.
To figure out if you need a server restart, I recommend doing the following:
Set up some monitoring tools like https://newrelic.com/ that let's your monitor your performance.
Monitor your memory continuously. Try to see if there is steady increase in the amount of memory consumed, or if it levels off.
Decide upon an acceptable threshold before you need to act. For example once your app consumes 60% of system memory you need to start thinking about a server restart and decide upon the restart interval.
Decide if you are ok with having "downtime" while restarting the sever or not. If you don't want downtime, you may need to build a proxy layer to direct traffic.
In general, I'd recommend server restarts for all dynamic, garbage collected languages. This is fairly common in those types of large applications. It is almost inevitable that a small mistake somewhere in your code base, or one of the libraries you depend on will leak memory. Even if you fix one leak, you'll get another one eventually. This may frustrate your team, which will basically lead to a server restart policy, and a definition of what is acceptable in regards to memory consumption for your application.
I agree with #Parris. You should probably figure out whether you actually need have a restart policy first. I would suggest using pm2 docs here. Even if you don't want to sign up for keymetrics, its a pretty good little process manager and real quick to set up. You can get a report of memory usage from command line. Looks something like this.
Also, if you start in cluster mode like above, you can call pm2 restart my_app and the first one will probably be up again before the last one is taken offline (this is an added benefit, the real reason for having 8 processes is to utilize all 8 cores). If you are adamant about downtime, you could restart them 1 by 1 acording to id.
I agree with #Parris this seems like a premature optimization. Also, restarting is not a solution to the underlying problem, it's a treatment for the symptoms.
If memory errors are a prevalent issue for your node application then I think that some thought as to why this fragmentation occurs in your program in the first place could be a valuable effort. Understanding why memory errors occur after a program has been running for a long period of time, and refactoring the architecture of your program to solve the root of the problem, is a better solution in my eyes than just addressing the symptoms.
I believe two things will benefit you.
immutable objects will help a lot, they are a lot more predictable than using mutable objects, and will not be affected by the length of time the project has been live. Also, since immutable objects are read only blocks of memory they are faster than mutable objects which the server has to spend resources deciding whether to read, or write on the memory block which stores the object. I currently use the library called IMMUTABLE and it works well for me. There are other one's as well like Deep Freeze, however, I have never used it.
Make sure to manage your application's processes correctly, memory leaks are the second big contributor to this problem that I have experienced. Again, this is solved by thinking about how your application is structured, and how user events are handled, making sure once a process is not being used by the client that it is properly removed from the heap, if it is not then the heap keeps growing until all memory is consumed causing the application to crash(refer to the below graphic to see V8's memory Scheme, and where the heap is). Node is a C++ program, and it's controlled by Google's V8 and Javascript.
You can use Node.js's process.memoryUsage() to monitor memory usage. When you identify how to manage your heap V8 offers two solutions, one is Scavenge which is very quick, but incomplete. The other is Mark-Sweep which is slow and frees up all non-referenced memory.
Refer to this blog post for more info on how to manage your heap and manage your memory on V8 which runs Node.js
So the responsible approach to your implementation is to keep a close eye on open processes, a deep understanding of the heap, and how to free non-referenced memory blocks. Creating your project with this in mind also makes the project a lot more scaleable as well.

JavaScript heap memory is constant, but the browser process private bytes are growing. Where does the memory difference come from?

I am troubleshooting what appears to be a memory leak in our configuration page. The page is used to change the configuration of our service and also displays health diagnostics. This means that we are querying the service periodically for configuration and instrumentation information (typically we use a query interval of 30sec, but to troubleshoot I am querying at 100ms intervals). We rely on knockoutjs, datajs, jquery and spinjs.
I've found that if I leave the page open overnight at the 100ms query interval that the private bytes for the chrome browser tab grows from about 50MB to 335MB. I have four pages with the issue, but am focused on one during my troubleshooting effort. Using chrome://memory-redirect/ I can see the page (process id 26148) memory.
However, the JavaScript heap memory appears to be flat over the same period at 3.6MB. Using the heap profiling tools in Chrome it shows that all of my object allocations are garbage collected.
In the above picture the gray allocations indicate that the objects have been cleaned up by the GC.
The memory timeline also is constant.
I also forced two GCs and confirmed that the number of documents, nodes and listeners was constant between the two GCs.
My questions are:
Where is the process memory being used that is not part of the JavaScript heap?
Given our JavaScript heap memory is flat, could that extra memory be a memory leak caused by our JavaScript code?
Thanks for all the help!
You are comparing apples and oranges - Garbage collected memory in a sub-heap and whole application memory.
You've used Chrome to inspect the JavaScript heap and found evidence that indicates the JavaScript part of your application is running OK.
You're also using a tool to monitor the global memory usage of Chrome itself. That is all the memory that Chrome is using for any task, including tasks not directly related to your application, but to the functioning of the browser itself.
Perhaps you've found a use case that triggers a memory leak in the Chrome internals?
Or perhaps it isn't a memory leak, but memory fragmentation in the non-garbage collected internal heaps used by Chrome?
According to this web page Chrome is written in a mixture of C, C++, Java, JavaScript and Python. This means we have deterministic memory allocators for C and C++ and three different types of garbage collected heaps for Java, JavaScript and Python. Bad news: Python's handling of integers isn't so kind on memory use when it comes to garbage collection (last time I checked, which was a few years ago, maybe they've improved it).
But I've had Chrome sessions run for weeks without issue. So I do wonder what is happening.
You don't say which OS you are using but if you are using Microsoft Windows then you could use C++ Memory Validator to inspect where each allocation was made (full callstack, how many bytes, etc) while Chrome is running (Launch Chrome from C++ Memory Validator, load your applicaton, let it do it's thing then go to the Memory tab and click Refresh - it will display all the live allocations that can be tracked - any statically linked heaps won't be trackable as you won't have the symbols to allow them to be hooked). OK, you don't have symbols to make teh callstacks readable but you can still identify allocations happening at the same place. That may give you a clue as to the cause of the leak/fragmentation so that can report this to the Chrome devs for a closer look.
Do you get the same behaviour in Firefox? If you then you could do what I suggest with C++ Memory Validator but do it on a build of Firefox that you've built yourself - you'll have symbols and source and know exactly where the problem is.
Disclaimer. I am the designer of C++ Memory Validator.

JavaScript instance vs prototype methods and heap snapshot data using Chrome Dev Tools

I have a heap profile taken in Chrome Dev Tools, but I am not sure how to interpret the data. As a test, I created 10,000 WidgetBuilder objects, each with their own methods. I would like to profile out storing methods on instances versus the prototype and see how that affects memory and performance when my page loads.
Should I focus on Retained Size or Shallow Size?
Are the values listed in these columns in bytes?
What is considered a lot of memory?
You might want to start here:
https://developers.google.com/chrome-developer-tools/docs/heap-profiling
It goes into detail on how to understand what you're reading. As for what is considered a lot of memory that's a tricky question. If your website is targeted at mobile devices I would start there as a constraint. To come up with a good comparison I'd suggest running the profiler against sites that you use every day and observe the memory consumption there.
If you find you're using more memory than gmail you might want to rethink ;)
I also recommend checking out jspref:
http://jsperf.com/prototype-vs-instance-functions
There is a LOT of prior work done on that site in regards to performance testing. You might be able to save yourself some time.

How to Identify A Memory Leak with Backbone.js

I believe I have a memory leak in my Backbone.js app. I concluded this after I printed some of my Backbone.View objects to the console, and saw the cid #'s increasing to the hundreds after just a bit clicking around.
Is this increasing cid# a sure sign of a memory leak? Are there any Heap profiling tools I can see the objects that are created, like with Java language? What are the best practices with Backbone.js to ensure no leaks?
Thanks!
The best practice is to use listenTo instead of on and bind. And do not forget to stopListening when you remove an instance.
I would suggest to use Chrome profiler for leaks detection: https://developers.google.com/chrome-developer-tools/docs/javascript-memory-profiling.
Also you can try to use Chrome plugin for debugging Backbone apps:
https://github.com/Maluen/Backbone-Debugger for debugging Backbone apps.
The profiler is the only source to find out where the leaks are. But there's a much simpler way to see the bigger picture. Go to the timeline then memory in chrome dev tools. It's much easier to read the graph and will show you spikes in memory and DOM creation/destruction.
You shouldn't worry about cleaning leaks until you're app manages the memory as best as possible. Users WILL notice memory spikes because the app will chug; They WON'T notice 99.9% of the leaks.
You're time would be better spend learning how to manage memory in the browser. Backbone doesn't do a good job managing memory. To use memory better: Use object pooling on DOM nodes, update DOM elements when the model changes, keep as much javascript as possible out of the templates, only use the render function once, be careful when loading images. There's a lot of techniques. Here's an example of the techniques to make you're backbone app performant: https://github.com/puppybits/BackboneJS-PerfView.

javascript performance memory leak

In my web application, when I load a js module, I will meet a performance problem. I can hardly do the drag-drop/click operation after the page run a few time (10+ mins).
So I think this must be caused by the js file, it may cause the memory leak, but I have not idea how to find the problem.
Any one can give me some suggestion?
I would give DynaTrace Ajax Edition a try.
Here is an article about one of the ways you can find memory leaks with Chrome's Developer Tools: https://developers.google.com/chrome-developer-tools/docs/heap-profiling.
Also, this article tells you about how memory leaks can take place in JavaScript, in general: http://www.javascriptkit.com/javatutors/closuresleak/index.shtml. The usual case is when there are circular references between JavaScript world and the DOM world. The JavaScript world does have a GC that knows how to clean up circular references, but the DOM world has an entirely different GC. Combining the two worlds in some ways (which look innocuous at first) can lead to memory leaks even in modern browsers.
If the memory fills up quickly it is often due to detached DOM trees. If these are canvas elements or images, they can take much more memory than they appear to in the profiler tool (because the image data is store somewhere else). This is just one example, of course - there are many ways in which you can fill up the memory quickly.
You want to use valgrind with the browser if you want to check for a memory leak.

Categories

Resources