0

Could anyone shred some light on why there seems to be such a great difference in memory footprint between the two examples shown below? I'm using node.js as environment.

They both produce the same result and mapping

var util = require('util');

var startMem = process.memoryUsage().heapUsed;

/*
var test = function() {

    var testvar = function() {
        this.innerTest1 = function() {
            this.someVal1 = "this is a test";
            this.someFunc1 = function() {
                return "this is another test";
            }
        }
        this.innerTest2 = function() {
            this.someVal2 = "this is a third test";
            this.someFunc2 = function() {
                return "this is a forth test";
            }
        }
    }
}
*/
//out:
//mem: 448088


var test = function() {
    var testvar = {
        innerTest1 : {
            someVal1 : "this is a test",
            someFunc1 : function() {
                return "this is another test"
            }
        },
        innerTest2 : {
            someVal2 : "this is a third test",
            someFunc2 : function() {
                return "this is a forth test"
            }
        }
    }
}

for (var i = 0; i < 50000; i++) {
    var testobj = new test();
}

//out:
//mem: 1060040


console.log("mem: " + (process.memoryUsage().heapUsed - startMem));
3
  • Is the loop also part of the first example? Commented Nov 3, 2013 at 18:18
  • These are not doing the same thing at all Commented Nov 3, 2013 at 18:19
  • if you did not call innerTest1 and innerTest2 in your first test case, then comparison is not fair: someVal1/someFunc1 and someVal2/someFunc2 won't get created. Commented Nov 3, 2013 at 18:21

2 Answers 2

1

The two snippets of code have entirely different behavior.

In the first example, the properties/functions are not set or created until the containing functions are invoked. However, the containing functions are never invoked.

For instance, given:

   this.innerTest1 = function() {
        // the property is NOT SET until this function is run
        this.someVal1 = "this is a test";
        // this function is NOT CREATED until this function is run
        this.someFunc1 = function() {
            return "this is another test";
        }
    }

Likewise, the same applies for assigning to innerTest1. Thus, the first example code is equivalent the following which is not very useful.

var testvar = function() {}

(The parsing can be considered a one-time cost.)

In the later example, every property is assigned and every function is created as part of the object literal evaluation.

Sign up to request clarification or add additional context in comments.

2 Comments

Ahh ok, makes sense. So it would be the same memory footprint if every function and property were called in the loop, in the first example?
@Rasive I'm not going to say "the same", but it will be much closer - or at least wildly different from the previous numbers.
1

In the first example functions are getting created lazily only when their parent function is called, but in the second example all members are initialized as part of the object literal.

If you are trying to reduce your memory footprint, you should make use of the prototype chain which will allow you to share functions between multiple instances.

Basically, rather than doing:

function test() {
    var testvar = {
        someFn: function () {}
    };
}

You can do:

var base = {
    someFn: function () {}
};

function test() {
    var testvar = Object.create(base);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.