nodejs memory leak : process usage increase more than heap - javascript

I got some memory leak issue on my nodejs app executed by openshift docker soulution.
when I try to monitor memory usage using process rss, I found process memory increased over time.
I'm trying to catch memory usage in process heap but memwatch, heapdump module can't show anything.
npm module showed heap size, and diff that size is under 50mb.
but process memory is still increasing and it uses over 150mb.
I thought It caused application leak issue so I try --expose-gc and called global.gc() but never helped.
how can I see where the process use memory or
does nodejs use OS memory more than that's max heap size?
(I showed memory usage increased over 4GB)
I want to fix it or want to see how nodejs use that memory.
thanks for read & answer :)

Related

How can I investigate memory issues in NodsJS on kubernetes

I am looking for a way to investigate one of our nodejs services that keeps getting the error
"FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory"
when testing our performance.
I am looking for a package or program that will give me a warning when there is a memory leak and maybe what exactly is leaking. I know there are the heapdump snapshots, but most of the packages save it to a file that when it is saved on the pod when the pod will crash, will disappear, but also it takes a lot of memory to take the snapshot.
Most of the articles I found are very old and use packages that are already deprecated or just use snapshots and use the chrome dev tools but nobody seems to explain what exactly the columns in the snapshot mean.
Long story short: Do you have any suggestions for how to or which program/package to us for investigating memory issues in a nodejs service that runs on kubernetes and most of its info is received via message queue and not just RestAPI?

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.

Why node.js process taking more memory than allocated

Can someone please explain why my Node.js process is taking more than allocated memory?
I assigned 4G of memory to Nodejs process (maximum supported on 64bit machine, as per Nodejs doc), but I have seen process touching 5.6g of RSS memory (way higher than 4g that I assigned)
This is how I am running the process
node -max-old-space-size=4096 processName.js
This is what my TOP command shows (RSS #4.6g)
max-old-space-size controls one aspect of node.js memory usage within the interpreter as used for the storage of Javascript objects (sometimes referred to as the V8 heap), not the entire memory usage of the whole process. For example, max-old-space-size has nothing to do with how much memory the native code portions of node.js use at all.
So, total memory usage can always be more than max-old-space-size.

Measuring memory consumption programmatically in PhantomJS

Is there a way to have a JavaScript code that would run as an automated test and measure a web-app memory consumption?
What I am looking for is a way to prevent memory leaks in an angular app by having automated tests as a part of CI build process informing me about memory issues as soon as they arise. I already have many JavaScript tests running in PhantomJS via Jasmine.
I would get that information from the operating system by grepping ps aux for the phantom process.

Phantomjs dies by high memory consumption

We are using phantomjs to run our qunit tests page on our TFS build server. Our version of test runner is built from below example
https://github.com/ariya/phantomjs/blob/master/examples/run-qunit.js
Over a period of time number of tests increased from hundreds to couple of thousands and on a fine day phantomjs started crashing. It literally dies saying upload the dump and when you see the dump it 0kb !!
When we took a closer look at it on process explorer we found that memory consumption by phantomjs keeps going up as phantomjs is running tests and eventually crashes somewhere 833MB.
Yes the same amount of memory was being utilized by chrome and IE ! And Yes-Yes our tests were leaking memory :(. We did fixed it, memory utilization is lowered by 50% on chrome and IE and we expected phantomjs will handle it now. But no, phantomjs still kept crashing, process explorer shows same memory consumption.
http://phantomjs.org/api/webpage/method/close.html
According to above documentation phantomjs releases heap allocation just on close ? Could that be the reason why our fixed test consumed less memory on chrome but not phantomjs ? And last how to fix this ? How to make phantomjs keep garbage collecting javascript objects to reduce heap allocation ?
Update 1 - 07/28
We took a work around. I did modified my script to execute my tests module by module. In loop after executing all tests for a module I call page.close so it releases the memory for each module and never keeps building the dead heap of objects. Not closing this question since since its a workaround and not a solution. Hope creators will fix this sometime.
There is a static method, QWebPageSettings::clearMemoryCache, that invokes WebKit's garbage collection. However, it clears all QWebPage memory cache for every instantiated QWebPage object and is therefore, currently, unsuitable for including as an option in PhantomJS.
The Github pull request is available here:
https://github.com/ariya/phantomjs/pull/11511
Here's the Google Groups discussion:
https://groups.google.com/forum/#!msg/phantomjs/wIDp9J7B-bE/v5U31_mTbswJ
Until a workaround is available, you might break up your unit tests into blocks on separate pages. It will take a change to QtWebkit's implementation and how memory/cache is handled across QWebPage objects.
Update September 2014:
https://github.com/ariya/phantomjs/commit/5768b705a0
It looks like support for clearing memory cache was added, but there is a note about my original comment in the commit.
I managed to work around it by setting the /LARGEADDRESSAWARE flag
If you have visual studio installed, run from a visual studio command prompt
editbin /LARGEADDRESSAWARE <pathto>/PhantomJS.exe

Categories

Resources