How big are Javascript function objects?

I was just wondering how the overhead is on a function object. In an OOP design model, you can spawn up a lot of objects each with their own private functions, but in the case where you have 10,000+, these private function objects, I assume, can make for a lot of overhead. I'm wondering if there are cases where it would be advantageous enough to move these functions to a utility class or external manager to save the memory taken up by these function objects.


This is how Chrome handles functions, and other engines may do different things.

Let's look at this code:

var funcs = [];
for (var i = 0; i < 1000; i++) {
    funcs.push(function f() {
        return 1;
    });
}
for (var i = 0; i < 1000; i++) {
    funcs[0]();
}

http://jsfiddle.net/7LS6B/4/

Now, the engine creates 1000 functions.

The individual function itself takes up almost no memory at all (36 bytes in this case), since it merely holds a pointer to a so-called SharedFunctionInfo object, which is basically a reference to the function definition in your source code*. This is called lazy parsing.

Only when you run it frequently does the JIT kick in, and creates a compiled version of the function, which requires more memory. So, funcs[0] takes up 256 bytes in the end:

堆分析器截图

*) this is not exactly true, it also holds scope information, the function's name and other metadata, which is why it has a size of 592 bytes in this case.


First of all it's common to place methods in the object constructor prototype, so they'll be shared among all instances of a given object:

function MyObject() {
    ....
}

MyObject.prototype.do_this = function() {
   ...
}

MyObject.prototype.do_that = function() {
   ...
}

Also note that a "function object" is a constant code-only block or a closure; in both cases the size is not related to the code:

x = [];
for (var i=0; i<1000; i++) {
    x.push(function(){ ... });
}

the size of each element of the array is not going to depend on the code size because the code itself will be shared between all of the function object instances. Some memory will be required for each of the 1000 instances, but it would be roughly the same amount required by other objects like strings or arrays and not related to how much code is present inside the function.

Things would be different if you create functions using Javascript eval : In that case I'd expect each function to take quite a bit and proportional to code size unless some super-smart caching and sharing is done also at this level.


Function objects do in fact take up a lot of space. Objects themselves may not take up much room as shown below but Function objects seem to take up considerably more. In order to test this, I used Function("return 2;") in order to create an array of anonymous functions.

The result was as implied by the OP. That these do in fact take up space.

Created

100,000 of these Function() 's created caused 75.4 MB to be used, from 0. I ran this test in a more controlled environment. This conversion is a little more obvious, where it indicates that each function object is going to consume 754 bytes. And these are empty. Larger function objects may surpass 1kb which will become significant very quickly. Spinning up the 75MB was non trivial on the client, and caused a near 4 second lock of the UI.

Here is the script I used to create the function objects:

fs = [];
for(var i = 0; i < 100000; i++ ){
 fs.push(Function("return 2;"));
}

Calling these functions also affects memory levels. Calling the functions added an additional 34MB of memory use.

Called 叫

This is what I used to call them:

for( var i = 0; i < fs.length; i++ ){
 for( var a = 0; a < 1000; a++ ){
     fs[i]();
 }
}

Using jsfiddle in edit mode is hard to get accurate results, I would suggest embedding it.

Embedded jsFiddle Demo


These statements are incorrect, I left them to allow the comments to retain context.

Function objects don't take very much space at all. The operating system and memory available are going to be what decides in the end how this memory is managed. This is not going to really impact anything on a scale which you should be worried about.

When loaded on my computer, a relatively blank jsfiddle consumed 5.4MB of memory. After creating 100,000 function objects it jumped to 7.5MB. This seems to be an insignificant amount of memory per function object (the implication being 21 bytes per function object: 7.5M-5.4M / 100k).

jsFiddle Demo

链接地址: http://www.djcxy.com/p/83126.html

上一篇: backbone.js模型指向嵌套模型的相同实例

下一篇: Javascript函数对象有多大?