我们假设ajax响应是5mb,我从ajax调用得到。
function(ajaxresponse){
var ajaxdata = ajaxresponse;
then
var ajaxdata2 = ajaxresponse; //as per the reply below this is a reference and hence new memory isn't allocated
var ajaxdata3 = JSON.parse(JSON.stringify(ajaxresponse));
}
是否会使用15mb,10mb或5mb?
答案 0 :(得分:1)
这很简单。 JavaScript总是按值传递/分配,但对象的值从不真正分配给变量。在JS中考虑对象和内存管理的方法是这样的:
所有对象(无论是函数,对象文字,数组,原型......)都驻留在内存中。内存中的这些空格可以由变量引用,也可以不引用。但他们保持 put 原样。您可以为任何数量的分配此对象的地址的变量,但不能直接复制对象本身,而不是直接复制。
查看this answer,其中包含许多图表以及有关JS如何工作的更多详细信息,包括指向更多信息的链接......
试试吧:
var a = {foo: 'bar'},
b;
b = a;
console.log(b.foo);//bar
b.foo += ' appended through b reference';
console.log(a.foo);//bar appended through b reference
a
和b
引用相同的对象,不需要额外的内存...保存存储b
变量所需的内存位数。
此示例中实际值为a
或b
的内容类似于0XB16B00B6
。或者在C语言中,它们实际上表现为一个解除引用的指针。
在某些情况下,人们做想要复制对象。由于JS的设计,现在很难完成。如果对象只包含数据,那么最简单的方法是:
var copiedObj = JSON.parse(JSON.stringify(someObject));
但是,如果你正在处理一个也有自己方法的对象,那么你将面临一个全新的麻烦世界,你将不得不做这样的事情:
//after doing:var copiedObj = JSON.parse(JSON.stringify(someObject));
function copyFunctions(srcObj, targetObj)
{
var prop;
for (prop in srcObj)
{
if (srcObj[prop] instanceof Object)
{
if (srcObj[prop] instanceof Function)
{
targetObj[prop] = srcObj[prop];//this is a REFERENCE, still
//OR, to ensure correct this binding!
targetObj[prop] = (function(rebind, actualFunc)
{
return function()
{
actualFunc.bind(this);
var returnVal = actualFunc.apply(this, [].slice.call(arguments));
actualFunc.bind(rebind);
};
}(srcObj, srcObj[prop]));
}
else
{
if (srcObj.hasOwnProperty(prop))
{//avoid copying prototypal methods
targetObj[prop] = copyFunctions(srcObj[prop], targetObj[prop] || {});
}
}
}
}
return targetObj;
}
请注意,此代码仅仅是我的头脑,并没有以任何方式进行测试。它没有检查递归,所以使用它是不安全的...但是我希望你能得到它的主旨。
现在,您的问题中的代码如何改变内存使用情况?简单:JSON.stringify
返回一个字符串常量。此字符串不再与原始对象绑定,因此JS将分配新内存以容纳此字符串的内存。然后,此字符串将传递给JSON.parse
。同样,将创建新对象,为此对象分配内存(不引用原始对象)是必需的。
在分配给ajaxdata3
之后,GC(GarbageCollector)启动。它将找到2个对单个对象的引用,因此该对象不能被GC控制。它还会注册第二个对象,该对象由变量ajaxdata3
引用,因此该对象也将保留在内存中。
还发现了JSON.stringify
的返回值,只是这次,GC看到这个字符串常量没有被引用到任何地方,因此它标记了内存的那一部分。 GC下次启动时,它会检查所有标记的位内存并取消分配它们(释放它们以供使用)。