memory consumption of Class instances

6 views
Skip to first unread message

Jon Hancock

unread,
Dec 16, 2009, 11:08:23 AM12/16/09
to MooTools Users
I've been writing some well factored moo code thanks to classes,
events and element storage. For example, I have model and view
objects which get associated with many elements. What I do not
understand is the memory footprint of my approach. There are tools
for analyzing memory in javascript, but its pretty low level stuff.
One thing I'd like to know:
When I instantiate a mootools Class, are my functions copied for each
instance? Is each instance only getting "slots" for pointers to each
function or is every function getting copied for each instance?
I am assuming mootools is handle garbage collection well for things I
associate with element storage. But I can't be certain as sometime it
seems my site gets slower the longer I keep testing with the same
browser window.
Any other things I should consider?
thanks, Jon

Roman Land

unread,
Dec 16, 2009, 11:14:21 AM12/16/09
to mootool...@googlegroups.com
I asked a similar question in the past, you can check the thread out here:
http://groups.google.com/group/mootools-users/browse_thread/thread/5aec78813fa51cc1/e1f59d8cf396c657?lnk=raot
--
---
"Make everything as simple as possible, but not simpler."

- Albert Einstein

Aaron Newton

unread,
Dec 16, 2009, 1:21:03 PM12/16/09
to mootool...@googlegroups.com
When I instantiate a mootools Class, are my functions copied for each
instance?  
 
No, this is how prototypal inheritance works. Consider an Array method like, say, push. Every array in memory does not have this function. Instead, Array.prototype has this method, and when the JS interpreter sees you reference it, it first looks at the array itself, and, not finding a property called "push" it looks at the array's prototype. If it didn't find it there, it would look at the array prototype's prototype and so on until it hit Object.prototype. This form of inheritance is very memory efficient.

Consequently, your class instances only have memory used to store the things you assign to them. For instance, if your initialize method looks like this:

initialize: function(element) {
  this.element = element;
}

now your class has an actual assignment for element, and it cannot inherit this property from its parent. In this case, this is just a pointer to an object already in memory (an element), but if you create an array or something, then that means every instance will have its own in memory:

nitialize: function() {
  this.array =[1,2,3];
}

This is not 100% accurate though. Because we don't want to copy references (so that a if one class instance changes a property that all class instances don't change). Because of this, all class properties that are arrays have to be copied, so if you have a class like this:

var X = new Class({
  foo: [1,2,3]
});

every time you create a new instance of X that array gets copied into memory.

I am assuming mootools is handle garbage collection well for things I
associate with element storage.  

This is correct. So long as you assign values to elements using only MooTools methods, and so long as you attach events and other such properties using MooTools methods, your code should garbage collect cleanly.
 
But I can't be certain as sometime it seems my site gets slower the longer I keep testing with the same
browser window.

You can test for memory leaks quite easily. Simply create a test (say, it creates an instance of your class), and put it in a loop that executes, say, 1000 times. Open up a memory viewer (for OSX it's just the Activity Monitory) and load your page. Then reload it. You should see the memory footprint reset on reload and return to were it was the first time you loaded the page. If you see it step up and up each time you reload, you have a leak. This is a little old, and I was running windows when I wrote it, but it still mostly holds true:


Jon Hancock

unread,
Dec 16, 2009, 2:05:00 PM12/16/09
to MooTools Users
thanks Aaron, that's just the kind of reassurance I was looking for.
I spent 10 years coding Smalltalk and another 7 in Java. I still
"think" in Smalltalk and so far that's helped write good javascript
code but I find javascript to be a bit opaque in its execution model
so your notes do help a lot.
Jon
> http://www.clientcide.com/best-practices/optimization/aha-memory-leak...

Sanford Whiteman

unread,
Dec 16, 2009, 2:10:30 PM12/16/09
to Jon Hancock
> I spent 10 years coding Smalltalk

Smalltalk on OS/2 FTW!

nwhite

unread,
Dec 16, 2009, 3:24:31 PM12/16/09
to mootool...@googlegroups.com

You can test for memory leaks quite easily. Simply create a test (say, it creates an instance of your class), and put it in a loop that executes, say, 1000 times. Open up a memory viewer (for OSX it's just the Activity Monitory) and load your page. Then reload it. You should see the memory footprint reset on reload and return to were it was the first time you loaded the page. If you see it step up and up each time you reload, you have a leak. This is a little old, and I was running windows when I wrote it, but it still mostly holds true:


As I’ve learned the hard way, accurately measuring memory usage is hard.  --- Pavlov (Mozilla Engineer)

The short summary is Windows Vista (Commit Size) and Linux (RSS) provide pretty accurate memory measurement numbers while Windows XP and MacOS X do not. 

On Mac, If you look at Activity Monitor it will look like we’re using more memory than we actually are. Mac OS X has a similar, but different, problem to Windows XP. After extensive testing and confirmation from Apple employees we realized that there was no way for an allocator to give unused pages of memory back while keeping the address range reserved.. (You can unmap them and remap them, but that causes some race conditions and isn’t as performant.) There are APIs that claim to do it (both madvise() and msync()) but they don’t actually do anything. It does appear that pages mapped in that haven’t been written to won’t be accounted for in memory stats, but you’ve written to them they’re going to show as taking up space until you unmap them. Since allocators will reuse space, you generally won’t have that many pages mapped in that haven’t been written to.

Sorry but using Activity Monitor is flawed on so many levels. If you really need to nail down memory usage or suspect memory usage using some kind of profiler is essential.


I know there are webkit specific resources as well, I'll try to dig them up.

Drip seems to be a relatively easy to use and provides decent results for testing memory leaks within IE.


Reply all
Reply to author
Forward
0 new messages