views:

3968

answers:

5

I want to know the size occupied by a JavaScript object.

Take the following function -

function Marks()
{
  this.maxMarks = 100;
}

function Student()
{
  this.firstName = "firstName";
  this.lastName = "lastName";
  this.marks = new Marks();
}

Now.. i instantiate the student

var stud = new Student();

so that I can do stuff like

stud.firstName = "new Firstname";

alert(stud.firstName);

stud.marks.maxMarks = 200;

etc...

now, stud object will occupy some size in memory. It has some data and more objects.

How do I find out how much memory the stud object occupies?

something like a sizeof() in JavaScript?

It would be really awesome if i could find it out in a single function call like

sizeof(stud)

P.S. I've been searching the Internet for months - couldn't find it (asked in a couple of forums - no replies).

+7  A: 

To the best of my knowledge JavaScript simply doesn't have anything that can help you here. the language is designed for a world where memory is freely available and the program will be lightweight. Measuring memory would both be beyond it's requirements and not necessary for almost anything you would care to write.

I imagine that the duck-typed nature of JS and the fact that it's highly implementation dependant would be a problem for determining memory consumption with your own language extensions. Almost everything I've ever seen used to benchmark JS memory leaks simply inspects the task manager. The most accurate solution I can think of if you really really had to know would be to get into the code of an OSS browser like firefox and create a plugin which watches this and reports it, and I very much doubt that would be worthwhile.

Summary: you can't and it's not worth knowing.

annakata
"you can't".. okay.. "not worth knowing".. i don't agree. I am sure my javascript code is taking up more memory - creating more objects unnecessarily. The difference in Firefox's memory usage - with and without my extension is something like 300MB+! If I am going to take steps to reduce mem comsumption, it DOES MATTER and it IS WORTH KNOWING how much memory my objects take up.
The amount of memory your JS is consuming is a fractional drop in the ocean compared to what the browser, pretty much unless you're writing code designed to strain the memory. You literally have to create and keep hundreds of thousands if not millions of objects in memory before you'll start creating a problem.
annakata
A: 

i want to know if my memory reduction efforts actually help in reducing memory

Following up on this comment, here's what you should do: Try to produce a memory problem - Write code that creates all these objects and graudally increase the upper limit until you ran into a problem (Browser crash, Browser freeze or an Out-Of-memory error). Ideally you should repeat this experiment with different browsers and different operating system.

Now there are two options: option 1 - You didn't succeed in producing the memory problem. Hence, you are worrying for nothing. You don't have a memory issue and your program is fine.

option 2- you did get a memory problem. Now ask yourself whether the limit at which the problem occurred is reasonable (in other words: is it likely that this amount of objects will be created at normal use of your code). If the answer is 'No' then you're fine. Otherwise you now know how many objects your code can create. Rework the algorithm such that it does not breach this limit.

Itay
From a memory stand point, my extension adds a number of objects for each page/tab that is open in Firefox. The "number" is proportional to the size of the page. Assuming that "power" users have anywhere between 15 - 20 tabs open, and if the web page has a lot of contents, the browser becomes slow and frustratingly non-responsive after some time. This happens even without me explicitly trying to stress the app. I have plans to rewrite the code that I think will reduce a lot of object creation. I just wanted to be sure that the no. of objects reduced amounted to something so that it is worth it
@Senthil: but object size has no meaning unless you know amount of available memory. Since amount of memory is likely to remain a mystery, speaking in terms of #objects is just as useful as speaking in term of #bytes
Itay
+1  A: 

This is a hacky method, but i tried it twice with different numbers and it seems to be consistent.

What you can do is to try and allocate a huge number of objects, like one or two million objects of the kind you want. Put the objects in an array to prevent the garbage collector from releasing them (note that this will add a slight memory overhead because of the array, but i hope this shouldn't matter and besides if you are going to worry about objects being in memory, you store them somewhere). Add an alert before and after the allocation and in each alert check how much memory the Firefox process is taking. Before you open the page with the test, make sure you have a fresh Firefox instance. Open the page, note the memory usage after the "before" alert is shown. Close the alert, wait for the memory to be allocated. Subtract the new memory from the older and divide it by the amount of allocations. Example:

function Marks()
{
  this.maxMarks = 100;
}

function Student()
{
  this.firstName = "firstName";
  this.lastName = "lastName";
  this.marks = new Marks();
}

var manyObjects = new Array();
alert('before');
for (var i=0; i<2000000; i++)
    manyObjects[i] = new Student();
alert('after');

I tried this in my computer and the process had 48352K of memory when the "before" alert was shown. After the allocation, Firefox had 440236K of memory. For 2million allocations, this is about 200KB for each object.

I tried it again with 1million allocations and the result was similar: 196KB per object (i suppose the extra data in 2mill was used for Array).

So, here is a hacky method that might help you. JavaScript doesn't provide a "sizeof" method for a reason: each JavaScript implementaion is different. In Google Chrome for example the same page uses about 66KB for each object (judging from the task manager at least).

Bad Sector
Hey.. thanks for the technique. I was having that as plan B incase no direct way was there to measure memory usage.
Each C and C++ implementation is also different. ;) The size of a data type in C or C++ is implementation specific. I see no reason JavaScript couldn't support such an operator, though it wouldn't serve the same purpose or have the same meaning as it does in C or C++ (which are lower-level languages and measure the actual size of a fixed-size data type at compile time as opposed to the variable-size of a dynamic JavaScript object at run-time).
bamccaig
A: 

i had the same problem while building http://mediabeez.ws/htmlMicroscope/

if you load that lib, you can transform a nested object/array like so:

--------- 11 jan 2010: CHANGED ------------

var test = hms.tools.augmentWithStatsData (hms.tools.cloneObject(arrayOrObject)); debugger;

augment... used to be named getRecursiveLength, which i found a bit too cryptic. btw, hm1.2.0, released today, is lots better than any previous version..

Rene
+1  A: 

If your main concern is the memory usage of your Firefox extension, I suggest checking with Mozilla developers.

Mozilla provides on its wiki a list of tools to analyze memory leaks.

Vincent Robert