Tracking down memory leaks using node-memwatch? - javascript

I am attempting to use node-memwatch to track down memory leaks in my application. Currently I am creating a HeapDiff when the app starts and then doing a diff when mem-watch detects a leak. I have found a few items that look suspect but I don't understand how I should map what is being reported to my code. For example, the following item is reported in the diff:
{ what: 'String',
size_bytes: 4785072,
size: '4.56 mb',
'+': 32780,
'-': 563 },
Which seems like a prime suspect for a memory leak. How can I figure out which piece of my code is causing this leak? In the examples they give on their site, what is typically something obvious like MyLeakyClass and not a system type...

It seems that feature is yet to be implemented:
"In particular, we want node-memwatch to be able to provide some examples of a leaked object (e.g., names of variables, array indices, or closure code)."
https://hacks.mozilla.org/2012/11/tracking-down-memory-leaks-in-node-js-a-node-js-holiday-season/
LeakingClass example should have been given from this code: https://github.com/lloyd/node-memwatch/blob/master/examples/basic_heapdiff.js

What that means is that you have created 32780 strings, and garbage collected 563, since starting your HeapDiff. (the ones you collected may or may not be ones created in this window; they could have existed already when the diff started). The total amount of memory used by strings has grown by 4.56mb. That could all be in one string, or it could be perfectly evenly distributed among the 32k strings. You have no data on that.
Strings, of course, show up all over your code. So my advice is, don't look at those. Look for objects with more trackable (greppable, rarer, whatever) names that are growing, even if they appear to be growing less than your strings, and track those. In the process, you may find your big leaks.

Related

How are arrays implemented in JavaScript? What happened to the good old lists?

JavaScript provides a variety of data structures to be used ranging from simple objects over arrays, sets, maps, the weak variants as well as ArrayBuffers.
Over the half past year I found myself in the spot to recreate some of the more common structures like Dequeues, count maps and mostly different variants of trees.
While looking at the Ecma specification I could not find a description on how arrays implemented on a memory level, supposedly this is up to the underlying engine?
Contrary to languages I am used to, arrays in JavaScript have a variable length, similar to list. Does that mean that elements are not necessarily aligned next to each other in memory? Does a splice push and pop actually result in new allocation if a certain threshold is reached, similar to for example ArrayLists in Java? I am wondering if arrays are the way to go for queues and stacks or if actual list implementations with references to the next element might be suited in JavaScript in some cases (e.g. regarding overhead opposed to the native implementation of arrays?).
If someone has some more in-depth literature, please feel encouraged to link them here.
While looking at the Ecma specification I could not find a description on how arrays implemented on a memory level, supposedly this is up to the underlying engine?
The ECMAScript specification does not specify or require a specific implementation. That is up to the engine that implements the array to decide how best to store the data.
Arrays in the V8 engine have multiple forms based on how the array is being used. A sequential array with no holes that contains only one data type is highly optimized into something similar to an array in C++. But, if it contains mixed types or if it contains holes (blocks of the array with no value - often called a sparse array), it would have an entirely different implementation structure. And, as you can imagine it may be dynamically changed from one implementation type to another if the data in the array changes to make it incompatible with its current optimized form.
Since arrays have indexed, random access, they are not implemented as linked lists internally which don't have an efficient way to do random, indexed access.
Growing an array may require reallocating a larger block of memory and copying the existing array into it. Calling something like .splice() to remove items will have to copy portions of the array down to the lower position.
Whether or not it makes more sense to use your own linked list implementation for a queue instead of an array depends upon a bunch of things. If the queue gets very large, then it may be faster to deal with the individual allocations of a list so avoid having to copy large portions of the queue around in order to manipulate it. If the queue never gets very large, then the overhead of a moving data in an array is small and the extra complication of a linked list and the extra allocations involved in it may not be worth it.
As an extreme example, if you had a very large FIFO queue, it would not be particularly optimal as an array because you'd be adding items at one end and removing items from the other end which would require copying the entire array down to insert or remove an item from the bottom end and if the length changed regularly, the engine would probably regularly have to reallocate too. Whether or not that copying overhead was relevant in your app or not would need to be tested with an actual performance test to see if it was worth doing something about.
But, if your queue was always entirely the same data type and never had any holes in it, then V8 can optimize it to a C++ style block of memory and when calling .splice() on that to remove an item can be highly optimized (using CPU block move instructions) which can be very, very fast. So, you'd really have to test to decide if it was worth trying to further optimize beyond an array.
Here's a very good talk on how V8 stores and optimizes arrays:
Elements Kinds in V8
Here are some other reference articles on the topic:
How do JavaScript arrays work under the hood
V8 array source code
Performance tips in V8
How does V8 optimize large arrays

Why should I use immutablejs over object.freeze?

I have researched on net about the benefits of immutablejs over Object.freeze() but didn't find anything satisfying!
My question is why I should use this library and work with non native data structures when I can freeze a plain old javascript object?
I don't think you understood what immutablejs offers. It's not a library which just turns your objects immutable, it's a library around working with immutable values.
Without simply repeating their docs and mission statement, I'll state two things it provides:
Types. They implemented (immutable) infinite ranges, stacks, ordered sets, lists, ...
All of their types are implemented as Persistent Data Structures.
I lied, here's a quote of their mission statement:
Immutable data cannot be changed once created, leading to much simpler application development, no defensive copying, and enabling advanced memoization and change detection techniques with simple logic. Persistent data presents a mutative API which does not update the data in-place, but instead always yields new updated data.
I urge you to read the articles and videos they link to and more about Persistent Data Structures (since they're the thing immutablejs is about), but I'll summarise in a sentence or so:
Let's imagine you're writing a game and you have a player which sits on a 2d plane. Here, for instance, is Bob:
var player = {
name: 'Bob',
favouriteColor: 'moldy mustard',
x: 4,
y: 10
};
Since you drank the FP koolaid you want to freeze the player (brrr! hope Bob got a sweater):
var player = Object.freeze({
name: 'Bob',
...
});
And now enter your game loop. On every tick the player's position is changed. We can't just update the player object since it's frozen, so we copy it over:
function movePlayer(player, newX, newY) {
return Object.freeze(Object.assign({}, player, { x: newX, y: newY }));
}
That's fine and dandy, but notice how much useless copying we're making: On every tick, we create a new object, iterate over one of our objects and then assign some new values on top of them. On every tick, on every one of your objects. That's quite a mouthful.
Immutable wraps this up for you:
var player = Immutable.Map({
name: 'Bob',
...
});
function movePlayer(player, newX, newY) {
return player.set('x', newX).set('y', newY);
}
And through the ノ*✧゚ magic ✧゚*ヽ of persistent data structures they promise to do the least amount of operations possible.
There is also the difference of mindsets. When working with "a plain old [frozen] javascript object" the default actions on the part of everything is to assume mutability, and you have to work the extra mile to achieve meaningful immutability (that's to say immutability which acknowledges that state exists). That's part of the reason freeze exists: When you try to do otherwise, things panic. With Immutablejs immutability is, of course, the default assumption and it has a nice API on top of it.
That's not to say all's pink and rosy with cherry on top. Of course, everything has its downsides, and you shouldn't cram Immutable everywhere just because you can. Sometimes, just freezeing an object is Good Enough. Heck, most of the time that's more than enough. It's a useful library which has its niche, just don't get carried away with the hype.
According to my benchmarks, immutable.js is optimized for write operations, faster than Object.assign(), however, it is slower for read operations. So the descision depends the type of your application and its read/write ratio. Following are the summary of the benchmarks results:
-- Mutable
Total elapsed = 103 ms = 50 ms (read) + 53 ms (write).
-- Immutable (Object.assign)
Total elapsed = 2199 ms = 50 ms (read) + 2149 ms (write).
-- Immutable (immutable.js)
Total elapsed = 1690 ms = 638 ms (read) + 1052 ms (write).
-- Immutable (seamless-immutable)
Total elapsed = 91333 ms = 31 ms (read) + 91302 ms (write).
-- Immutable (immutable-assign (created by me))
Total elapsed = 2223 ms = 50 ms (read) + 2173 ms (write).
Ideally, you should profile your application before introducing any performance optimization, however, immutability is one of those design decision must be decided early. When you start using immutable.js, you need to use it throughout your entire application to get the performance benefits, because interop with plain JS objects using fromJS() and toJS() is very costly.
PS: Just found out that deep freeze'ed array (1000 elements) become very slow to update, about 50 times slower, therefore you should only use deep freeze in development mode only. Benchmarks results:
-- Immutable (Object.assign) + deep freeze
Total elapsed = 45903 ms = 96 ms (read) + 45807 ms (write).
Both of them don't make the object deeply immutable.
However, using Object.freeze you'll have to create the new instances of the object / array by yourself, and they won't have structural sharing. So every change which will require deeply copying everything, and the old collection will be garbage collected.
immutablejs on the other hand will manage the collections, and when something changes, the new instance will use the parts of the old instance that haven't changed, so less copying and garbage collecting.
There are a couple of major differences between Object.freeze() and immutable.js.
Let's address the performance cost first. Object.freeze() is shallow. It will make the object immutable, but the nested properties and methods inside said object can still be mutated. The Object.freeze() documentation addresses this and even goes on to provide a "deepFreeze" function, which is even more costly in terms of performance. Immutable.js on the other hand will make the object as a whole (nested properties, method, etc) immutable at a lower cost.
Additionally should you ever need to clone an immutable variable Object.freeze() will force you to create an entirely new variable, while Immutable.js can reuse the existing immutable variable to create the clone more efficiently. Here's an interesting quote about this from this article:
"Immutable methods like .set() can be more efficient than cloning
because they let the new object reference data in the old object: only
the changed properties differ. This way you can save memory and
performance versus constantly deep-cloning everything."
In a nutshell, Immutable.js makes logical connections between the old and new immutable variables, thus improving the performance of cloning and the space frozen variables take in memory. Object.freeze() sadly does not - every time you clone a new variable from a frozen object you basically write all the data anew, and there is no logical connection between the two immutable variables even if (for some odd reason) they hold identical data.
So in terms of performance, especially if you constantly make use of immutable variables in your program, Immutable.js is a great choice. However, performance is not everything and there are some big caveats to using Immutable.js. Immutable.js uses it's own data structure, which makes debugging, or even just logging data to the console, a royal pain. It also might lead to a loss of basic JavaScript functionality (for example, you cannot use ES6 de-structuring with it) The Immutable.js documentation is infamously impossible to understand (because it was originally written for use only within Facebook itself), requiring a lot of web-searching even when simple issues arise.
I hope this covers the most important aspects of both approaches and helps you decide which will work best for you.
Object.freeze does not do any deep freezing natively, I believe that immutable.js does.
The same with any library -- why use underscore, jquery, etc etc.
People like re-using the wheels that other people built :-)
The biggest reason that comes to mind - outside of having a functional api that helps with immutable updates, is the structural sharing utilized by Immutable.js. If you have an application that needs enforced immutability (ie, you're using Redux) then if you're only using Object.freeze then you're going to be making a copy for every 'mutation'. This isn't really efficient over time, since this will lead to GC thrasing. With Immutable.js, you get structural sharing baked in (as opposed to having to implement an object pool/a structural sharing model of your own) since the data structures returned from immutable are Tries. This means that all mutations are still referenced within the data structure, so GC thrashing is kept to a minimum. More about this is on Immutable.js's docsite (and a great video going into more depth by the creator, Lee Byron):
https://facebook.github.io/immutable-js/

How would you explain Javascript Typed Arrays to someone with no programming experience outside of Javascript?

I have been messing with Canvas a lot lately, developing some ideas I have for a web-based game. As such I've recently run into Javascript Typed Arrays. I've done some reading for example at MDN and I just can't understand anything I'm finding. It seems most often, when someone is explaining Typed Arrays, they use analogies to other languages that are a little beyond my understanding.
My experience with "programming," if you can call it that (and not just front-end scripting), is pretty much limited to Javascript. I do feel as though I understand Javascript pretty well outside of this instance, however. I have deeply investigated and used the Object.prototype structure of Javascript, and more subtle factors such as variable referencing and the value of this, but when I look at any information I've found about Typed Arrays, I'm just lost.
With this frame-of-reference in mind, can you describe Typed Arrays in a simple, usable way? The most effective depicted use-case, for me, would be something to do with Canvas image data. Also, a well-commented Fiddle would be most appreciated.
In typed programming languages (to which JavaScript kinda belongs) we usually have variables of fixed declared type that can be dynamically assigned values.
With Typed Arrays it's quite the opposite.
You have a fixed chunk of data (represented by ArrayBuffer) that you do not access directly. Instead this data is accessed by views. Views are created at run time and they effectively declare some portion of the buffer to be of a certain type. These views are sub-classes of ArrayBufferView. The views define the certain continuous portion of this chunk of data as elements of an array of a certain type. Once the type is declared browser knows the length and content of each element, as well as a number of such elements. With this knowledge browsers can access individual elements much more efficiently.
So we dynamically assigning a type to a portion of what actually is just a buffer. We can assign multiple views to the same buffer.
From the Specs:
Multiple typed array views can refer to the same ArrayBuffer, of different types,
lengths, and offsets.
This allows for complex data structures to be built up in the ArrayBuffer.
As an example, given the following code:
// create an 8-byte ArrayBuffer
var b = new ArrayBuffer(8);
// create a view v1 referring to b, of type Int32, starting at
// the default byte index (0) and extending until the end of the buffer
var v1 = new Int32Array(b);
// create a view v2 referring to b, of type Uint8, starting at
// byte index 2 and extending until the end of the buffer
var v2 = new Uint8Array(b, 2);
// create a view v3 referring to b, of type Int16, starting at
// byte index 2 and having a length of 2
var v3 = new Int16Array(b, 2, 2);
The following buffer and view layout is created:
This defines an 8-byte buffer b, and three views of that buffer, v1,
v2, and v3. Each of the views refers to the same buffer -- so v1[0]
refers to bytes 0..3 as a signed 32-bit integer, v2[0] refers to byte
2 as a unsigned 8-bit integer, and v3[0] refers to bytes 2..3 as a
signed 16-bit integer. Any modification to one view is immediately
visible in the other: for example, after v2[0] = 0xff; v21 = 0xff;
then v3[0] == -1 (where -1 is represented as 0xffff).
So instead of declaring data structures and filling them with data, we take data and overlay it with different data types.
I spend all my time in javascript these days, but I'll take a stab at quick summary, since I've used typed arrays in other languages, like Java.
The closest thing I think you'll find in the way of comparison, when it comes to typed arrays, is a performance comparison. In my head, Typed Arrays enable compilers to make assumptions they can't normally make. If someone is optimizing things at the low level of a javascript engine like V8, those assumptions become valuable. If you can say, "Data will always be of size X," (or something similar), then you can, for instance, allocate memory more efficiently, which lets you (getting more jargon-y, now) reduce how many times you go to access memory and it's not in a CPU cache. Accessing CPU cache is much faster than having to go to RAM, I believe. When doing things at a large scale, those time savings add up quick.
If I were to do up a jsfiddle (no time, sorry), I'd be comparing the time it takes to perform certain operations on typed arrays vs non-typed arrays. For example, I imagine "adding 100,000 items" being a performance benchmark I'd try, to compare how the structures handle things.
What I can do is link you to: http://jsperf.com/typed-arrays-vs-arrays/7
All I did to get that was google "typed arrays javascript performance" and clicked the first item (I'm familiar with jsperf, too, so that helped me decide).

Does assigning a new string value create garbage that needs collecting?

Consider this javascript code:
var s = "Some string";
s = "More string";
Will the garbage collector (GC) have work to do after this sort of operation?
(I'm wondering whether I should worry about assigning string literals when trying to minimize GC pauses.)
e: I'm slightly amused that, although I stated explicitly in my question that I needed to minimize GC, everyone assumed I'm wrong about that. If one really must know the particular details: I've got a game in javascript -- it runs fine in Chrome, but in Firefox has semi-frequent pauses, that seem to be due to GC. (I've even checked with the MemChaser extension for Firefox, and the pauses coincide exactly with garbage collection.)
Yes, strings need to be garbage-collected, just like any other type of dynamically allocated object. And yes, this is a valid concern as careless allocation of objects inside busy loops can definitely cause performance issues.
However, string values are immutable (non-changable), and most modern JavaScript implementations use "string interning", that is they store only one instance of each unique string value. This means that if you have something like this...
var s1 = "abc",
s2 = "abc";
...only one instance of "abc" will be allocated. This only applies to string values, not String objects.
A couple of things to keep in mind:
Functions like substring, slice, etc. will allocate a new object for each function call (if called with different parameters).
Even though both variable point to the same data in memory, there are still two variables to process when the GC cycle runs. Having too many local variables can also hurt you as each of them will need to be processed by the GC, adding overhead.
Some further reading on writing high-performance JavaScript:
https://developer.mozilla.org/en-US/docs/JavaScript/Memory_Management
https://www.scirra.com/blog/76/how-to-write-low-garbage-real-time-javascript
http://jonraasch.com/blog/10-javascript-performance-boosting-tips-from-nicholas-zakas
Yes, but unless you are doing this in a loop millions of times it won't likely be a factor for you to worry about.
As you already noticed, JavaScript is not JavaScript. It runs on different platforms and thus will have different performance characteristics.
So the definite answer to the question "Will the GC have work to do after this sort of operation?" is: maybe. If the script is as short as you've shown it, then a JIT-Compiler might well drop the first string completely. But there's no rule in the language definition that says it has to be that way or the other way. So in the end it's like it is all too often in JavaScript: you have to try it.
The more interesting question might also be: how can you avoid garbage collection. And that is try to minimize the allocation of new objects. Games typically have a pretty constant amount of objects and often there won't be new objects until an old one gets unused. For strings this might be harder as they are immutable in JS. So try to replace strings with other (mutable) representations where possible.
Yes, the garbage collector will have a string object containing "Some string" to get rid of. And, in answer to your question, that string assignment will make work for the GC.
Because strings are immutable and are used a lot, the JS engine has a pretty efficient way of dealing with them. You should not notice any pauses from garbage collecting a few strings. The garbage collector has work to do all the time in the normal course of javascript programming. That's how it's supposed to work.
If you are observing pauses from GC, I rather doubt it's from a few strings. There is more likely a much bigger issue going on. Either you have thousands of objects needing GC or some very complicated task for the GC. We couldn't really speculate on that without study of the overall code.
This should not be a concern unless you were doing some enormous loop and dealing with tens of thousands of objects. In that case, one might want to program a little more carefully to minimize the number of intermediate objects that are created. But, absent that level of objects, you should first right clear, reliable code and then optimize for performance only when something has shown you that there is a performance issue to worry about.
To answer your question "I'm wondering whether I should worry about assigning string literals when trying to minimize GC pauses": No.
You really don't need to worry about this sort of thing with regard to garbage collection.
GC is only a concern when creating & destroying huge numbers of Javascript objects, or large numbers of DOM elements.

How can I determine what objects are being collected by the garbage collector?

I have significant garbage collection pauses. I'd like to pinpoint the objects most responsible for this collection before I try to fix the problem. I've looked at the heap snapshot on Chrome, but (correct me if I am wrong) I cannot seem to find any indicator of what is being collected, only what is taking up the most memory. Is there a way to answer this empirically, or am I limited to educated guesses?
In chrome profiles takes two heap snapshots, one before doing action you want to check and one after.
Now click on second snapshot.
On the bottom bar you will see select box with option "summary". Change it to "comparision".
Then in select box next to it select snaphot you want to compare against (it should automaticaly select snapshot1).
As the results you will get table with data you need ie. "New" and "Deleted" objects.
With newer Chrome releases there is a new tool available that is handy for this kind of task:
The "Record Heap Allocations" profiling type. The regular "Heap SnapShot" comparison tool (as explained in Rafał Łużyński answers) cannot give you that kind of information because each time you take a heap snapshot, a GC run is performed, so GCed objects are never part of the snapshots.
However with the "Record Heap Allocations" tool constantly all allocations are being recorded (that's why it may slow down your application a lot when it is recording). If you are experiencing frequent GC runs, this tool can help you identify places in your code where lots of memory is allocated.
In conjunction with the Heap SnapShot comparison you will see that most of the time a lot more memory is allocated between two snapshots, than you can see from the comparison. In extreme cases the comparison will yield no difference at all, whereas the allocation tool will show you lots and lots of allocated memory (which obviously had to be garbage collected in the meantime).
Unfortunately the current version of the tool does not show you where the allocation took place, but it will show you what has been allocated and how it is was retained at the time of the allocation. From the data (and possibly the constructors) you will however be able to identify your objects and thus the place where they are being allocated.
If you're trying to choose between a few likely culprits, you could modify the object definition to attach themselves to the global scope (as list under document or something).
Then this will stop them from being collected. Which may make the program faster (they're not being reclaimed) or slower (because they build up and get checked by the mark-and-sweep every time). So if you see a change in performance, you may have found the problem.
One alternative is to look at how many objects are being created of each type (set up a counter in the constructor). If they're getting collected a lot, they're also being created just as frequently.
Take a look at https://developers.google.com/chrome-developer-tools/docs/heap-profiling
especially Containment View
The Containment view is essentially a "bird's eye view" of your
application's objects structure. It allows you to peek inside function
closures, to observe VM internal objects that together make up your
JavaScript objects, and to understand how much memory your application
uses at a very low level.
The view provides several entry points:
DOMWindow objects — these are objects considered as "global" objects
for JavaScript code; GC roots — actual GC roots used by VM's garbage
collector; Native objects — browser objects that are "pushed" inside
the JavaScript virtual machine to allow automation, e.g. DOM nodes,
CSS rules (see the next section for more details.) Below is the
example of what the Containment view looks like:

Categories

Resources