关于前端内存相关的问题?

新手上路,请多包涵
class B { }


class A {
  constructor() {
    this.b = new B()
  }
}
class BList {
  constructor() {
    this.values = []
  }
  push(b) {
    this.values.push(b)
  }
}
const aArray = Array(1000).fill('').map(() => new A())
var bList = new BList()
//aArray.forEach(a => { bList.push(a.b) })

图片
在放开最后一行注释后执行 : A的引用内存反而降低了,A对B的引用好像并没有解除,为什么会降低内存了?
图片

为什么A对象的内存降低了呢

==========================================update

class B {}

class A {
  constructor () {
    this.b = new B()
  }
}

class BList {
  constructor () {
    this.values = []
  }
  push (b) {
    this.values.push(b)
  }
}

const aArray = Array(1000000).fill('').map(() => new A())
const bList = new BList()
aArray.forEach(a => { bList.push(a.b) })

image.png

1.Blist.values 对应的指针;
2.A.b 对应的指针;
3.Blist.values 指向的数组的指针。

这三个对象是指这样吗,可不可以解释一下

阅读 1.1k
avatarAI BotBETA

在JavaScript中,对象的内存占用不仅仅取决于该对象本身,还与其引用的其他对象有关。当一个对象被引用时,JavaScript的垃圾回收器不会回收这个对象,因为其他对象可能需要它。在你的例子中,当aArray存在时,每一个A对象都有一个对B对象的引用,这使得B对象不能被垃圾回收。

当你取消最后一行注释后,你实际上是在创建一个新的BList对象,这个对象存储了所有A对象的b属性。这意味着B对象现在被BList对象引用,而不仅仅是A对象。由于BList对象仍然存在,垃圾回收器不能回收这些B对象。

但是,当aArray不再需要时(例如,当你离开当前作用域或者你明确地将其设为null),这些A对象就不再引用任何东西。因为它们不再直接或间接地引用任何东西,垃圾回收器可以安全地回收这些对象和它们引用的B对象。这就是为什么你看到内存使用量下降了。

所以,尽管A对象的内存降低了,但这是因为A对象的引用已经不存在了,而不是因为A对象释放了对B对象的引用。实际上,A对象仍然持有对B对象的引用,直到A对象本身被垃圾回收。

1 个回答
✓ 已被采纳

retained size指的是A对象被回收时,总共可以回收的内存大小
当B对象被其他对象引用后,A对象回收后不能使B对象也回收,所以retained size不会包含B对象的内存大小

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题