我想知道JavaScript对象占用的大小。
取以下函数:
function Marks(){
this.maxMarks = 100;
}
function Student(){
this.firstName = "firstName";
this.lastName = "lastName";
this.marks = new Marks();
}
现在我实例化这个学生:
var stud = new Student();
这样我就可以做
stud.firstName = "new Firstname";
alert(stud.firstName);
stud.marks.maxMarks = 200;
etc.
现在,stud对象将在内存中占据一定大小。它有一些数据和更多的对象。
我如何找出有多少内存stud对象占用?类似于JavaScript中的sizeof() ?如果我能在一个函数调用中找到它,比如sizeof(stud),那就太棒了。
我已经在网上搜索了几个月了——没有找到它(在几个论坛上被问到——没有回复)。
我使用Chrome开发工具的Timeline选项卡,实例化越来越多的对象,并得到像这样的良好估计。你可以像下面这样使用html作为样板,并修改它以更好地模拟对象的特征(属性的数量和类型等)。您可能希望在运行之前和之后单击开发工具选项卡底部的“垃圾位”图标。
<html>
<script>
var size = 1000*100
window.onload = function() {
document.getElementById("quantifier").value = size
}
function scaffold()
{
console.log("processing Scaffold...");
a = new Array
}
function start()
{
size = document.getElementById("quantifier").value
console.log("Starting... quantifier is " + size);
console.log("starting test")
for (i=0; i<size; i++){
a[i]={"some" : "thing"}
}
console.log("done...")
}
function tearDown()
{
console.log("processing teardown");
a.length=0
}
</script>
<body>
<span style="color:green;">Quantifier:</span>
<input id="quantifier" style="color:green;" type="text"></input>
<button onclick="scaffold()">Scaffold</button>
<button onclick="start()">Start</button>
<button onclick="tearDown()">Clean</button>
<br/>
</body>
</html>
在我的Chromium上,实例化200万个对象,每个对象只有一个属性(如上面的代码所示)导致每个对象的粗略计算为50个字节。更改代码为每个对象创建一个随机字符串会为每个对象增加大约30个字节,等等。
希望这能有所帮助。
在@Dan已经很紧凑的解决方案的基础上,这里有一个它的自包含函数版本。对于那些希望变量名尽可能紧凑而不考虑上下文的人来说,变量名被简化为单个字母。
const ns = {};
ns.sizeof = function(v) {
let f = ns.sizeof, //this needs to match the name of the function itself, since arguments.callee.name is defunct
o = {
"undefined": () => 0,
"boolean": () => 4,
"number": () => 8,
"string": i => 2 * i.length,
"object": i => !i ? 0 : Object
.keys(i)
.reduce((t, k) => f(k) + f(i[k]) + t, 0)
};
return o[typeof v](v);
};
ns.undef;
ns.bool = true;
ns.num = 1;
ns.string = "Hello";
ns.obj = {
first_name: 'John',
last_name: 'Doe',
born: new Date(1980, 1, 1),
favorite_foods: ['Pizza', 'Salad', 'Indian', 'Sushi'],
can_juggle: true
};
console.log(ns.sizeof(ns.undef));
console.log(ns.sizeof(ns.bool));
console.log(ns.sizeof(ns.num));
console.log(ns.sizeof(ns.string));
console.log(ns.sizeof(ns.obj));
console.log(ns.sizeof(ns.obj.favorite_foods));
接受的答案不适用于Map, Set, WeakMap和其他可迭代对象。(在其他回答中提到的包object-sizeof也有同样的问题)。
这是我的解决方案
export function roughSizeOfObject(object) {
const objectList = [];
const stack = [object];
const bytes = [0];
while (stack.length) {
const value = stack.pop();
if (value == null) bytes[0] += 4;
else if (typeof value === 'boolean') bytes[0] += 4;
else if (typeof value === 'string') bytes[0] += value.length * 2;
else if (typeof value === 'number') bytes[0] += 8;
else if (typeof value === 'object' && objectList.indexOf(value) === -1) {
objectList.push(value);
if (typeof value.byteLength === 'number') bytes[0] += value.byteLength;
else if (value[Symbol.iterator]) {
// eslint-disable-next-line no-restricted-syntax
for (const v of value) stack.push(v);
} else {
Object.keys(value).forEach(k => {
bytes[0] += k.length * 2; stack.push(value[k]);
});
}
}
}
return bytes[0];
}
它还包括其他一些小的改进:计算键存储和与ArrayBuffer一起工作。
我使用Chrome开发工具的Timeline选项卡,实例化越来越多的对象,并得到像这样的良好估计。你可以像下面这样使用html作为样板,并修改它以更好地模拟对象的特征(属性的数量和类型等)。您可能希望在运行之前和之后单击开发工具选项卡底部的“垃圾位”图标。
<html>
<script>
var size = 1000*100
window.onload = function() {
document.getElementById("quantifier").value = size
}
function scaffold()
{
console.log("processing Scaffold...");
a = new Array
}
function start()
{
size = document.getElementById("quantifier").value
console.log("Starting... quantifier is " + size);
console.log("starting test")
for (i=0; i<size; i++){
a[i]={"some" : "thing"}
}
console.log("done...")
}
function tearDown()
{
console.log("processing teardown");
a.length=0
}
</script>
<body>
<span style="color:green;">Quantifier:</span>
<input id="quantifier" style="color:green;" type="text"></input>
<button onclick="scaffold()">Scaffold</button>
<button onclick="start()">Start</button>
<button onclick="tearDown()">Clean</button>
<br/>
</body>
</html>
在我的Chromium上,实例化200万个对象,每个对象只有一个属性(如上面的代码所示)导致每个对象的粗略计算为50个字节。更改代码为每个对象创建一个随机字符串会为每个对象增加大约30个字节,等等。
希望这能有所帮助。