Hello everyone, and welcome back! My name is Gergely Nemeth, and I’m one of the founders of RisingStack, and also the co-author of the Node Hero blogpost series. In the past videos, we have learned how you can debug Node.js applications easily, and how you can handle asynchronous operations to build performant applications using them. So in this next video, I’m going to show you how you can use profilers, and how you can take heapdumps to find CPU bottlenecks and also to solve memory leaks, so let’s get started! First, I’d like to show you how you can grab CPU profiles. First of all, I’m going to use the v8-profiler modules. You can simply install it from npm.
Once you have that, you have to require it into your process, and also the filesystem (‘fs’) module, as I’m going to persist the given profile for the filesystem, so later on we can work with that. The first thing we have to do is start profiling the process, using the startProfiling function. Please note, that I’m adding an extra setTimeout for the process, so after two seconds, I’m going to stop the profiling itself. To do that, I’m calling the stopProfiling function on the profiler, and as a return value we grab the profile. On the profile we are calling the export function, and once we have the result, we are simply writing it to a file. In this case it’s called nodehero.cpuprofile – once we have that, we delete the profile, and for the sake of simplicity, we are exiting the process. So let’s run this example! Once we have it, the cpuprofile file will show up in our filesystem. Now it’s time to actually make sense of it, so to do that, open up your Chrome, and in Chrome, open up the developer tools.
Once we have that open, head over to the profiles tab and click load. So I just selected the CPU profile, and once it’s loaded, it will just show up on the left side. So, what you see here is actually the CPU profile you have just grabbed. You can select a couple of views, and you can see exactly how many milliseconds a given function call took. Because it’s a really simple example, there’s not a lot of things you can take a look at, but at least what we can take a look at is the very first part of this whole CPU profile, where we can take a look at the boot-up of the process, and how much time each function took. But now let’s take a look at a more sophisticated example! I’ve just loaded the CPU profile which was grabbed from our production systems. It’s actually our engineering blog, which is available at blog.risingstack.com – so now let’s take a look at how a CPU profile from a production system looks like. So, actually what you can see here are a couple of function calls, so you can see that in this case which function called which function, and how much time did each function call took.
But also, we can take a look at other examples as well, so you can see that in this case possibly a request was unserved, and this is why we see all the responses, and all the sockets. So when this profile was taken, probably a request was served to one of our readers. Memory heapdumps can be really useful if you are looking for memory leaks. We are going to use the very same module we used previously – the V8 profiler. To do find memory leaks, first you have to grab memory snapshots. To do that, first I’m creating a snapshot with the profiler.takeSnapshot function. Once we have the function, I’m going to simply write it to the filesystem as I did previously – so it will be available as nodehero.heapsnapshot, but also, if you are looking for memory leaks grabbing just one memory heapdump is not enough! You have to compare a given heapdump taken at a given time, to an other which was taken later on.
For that, after two seconds, I’m grabbing another one called nodehero-2.heapsnapshot, and I’m simply going to compare them using the Chrome developer tools, as we did previously. So let’s run this one, and head over to Chrome to inspect those memory heapdumps. So just click load, and open up your memory heapdumps. Once you have that, on the left side the heapsnapshots will show up for you. If you click the first one, you can take a look at all the memory objects that are present, and if you click the second one, you can take a look at that as well. So let’s see how you can actually compare those! Luckily for us, the Chrome developer tools comes with a comparison view, so in the summary section, just click comparison, and you can select that you want to compare it with ‘nodehero-2’, and you can see what other objects were allocated, during that time.
So in that two seconds, we can see that the compiled code size grew, the array size grew, and some strings were created as well. So, you can dive deeper into these allocations, and what you can see at the end are all the retainers of a given object, so why it’s actually in the memory, and which object keeps a reference to it, and you can continue to look for memory leaks based on this information. I hope you enjoyed this series, and learned a lot from us, but there is much more to it to become a better Node.js developer! So this is why I’m inviting you to our Node Hero program, where we are going to teach you all the best practices trough webinars, provide you live-coaching sessions, and a Trace accounts, so you can debug and monitor your applications in an easier way.
So, if you’d like to become a better Node.js developer, join our Node Hero program! See you there!.