CNode

对象用数字作为key时会内存泄漏

问答
Hheqs发布于9 年前最后回复9 年前10 回复6082 浏览0 收藏
this.watchers={ "creature": { id: id} };//如果这样赋值大小正常,200多字节
this.watchers["creature"][id]=id//如果这样赋值,这个对象竟然达到了惊人的12KB,并且ID越大占用内存越大,id=1占用200多字节,id=1000占用12KB
this.watchers["creature"]["_"+id]=id//这样写也正常

大神们这是为什么啊

查看回复

回复 (10)

A
anotherWill#1·9 年前

会不会当成数组了。。。用.id呢

H
heqs#2·9 年前
引用 anotherWill会不会当成数组了。。。用.id呢

@anotherWill id是动态的具体数字,不能用这种方式写吧

F
fightAndLearn#3·9 年前

应该是被置换为数组了obj[1234],生成了一个含有1234个元素的数组,对象属性用字符串,你应该用${id}

J
Jiasm#4·9 年前

这个绝壁是处理为数组了。。。

你可以选择用

Object.assign(this.watchers["creature"], {id: id})

或者初始化时就创建一个{}

Q
qingmingsang#5·9 年前

感觉很奇怪啊,我本地试了下不会转成数组

W
wbget#6·9 年前

Object的key,数字默认是会转换成string的。

H
heqs#7·9 年前

好像是V8对key为数字的object做的优化,在key小于1024时会转换为array,array有序读取很快,不过会消耗更大的内存,arr[1013]不是一个对象而是一个长度为1013的数组了

I
ianchn#8·9 年前

好坑。。。

V
vincentLiuxiang#10·9 年前

解释1

任何对象(json对象/数组)的属性,v8都会按字符串索引。 因此:

var a = [1,2,3,4];
console.log(a[1], a['1']) // 2, 2

虽然,this.watchers["creature"][id]=id, id为数字,但事实上内存存储的时候,id作为属性还是会存为字符串。

解释二

任何对象,在v8内部都会按以下结构保存 image.png 具体,请看考这篇文章 http://www.jayconrod.com/posts/52/a-tour-of-v8-object-representation

正如你说的,因为 id 为数字,对象内部存储时,会把数字属性存在数组里。

  • 如果 数组比较紧凑,就按连续数组存,比如 var obj = {1:1, 2:1, 9:1}, 内部就会产生一个长度至少为10的数组,好处是访问速度快,坏处是浪费内存。
  • 如果 数组比较疏松,数字属性,会触发字典模式,其好处是节省内存,坏处是反复hash处理,访问速度慢。

“this.watchers["creature"]["_"+id]=id//这样写也正常” 的原因也解释了吧;

另问一下:对象内存你是用是方法查看的?

参与回复
登录后即可参与回复。登录