Skip to content

js内存模型 #113

@et-hh

Description

@et-hh

基本模型

image

分配/使用 -》 回收

分配

基本类型

基本类型直接把值存于堆中。

基本类型值改变时会产生一个新的值

引用类型

引用类型在栈中存引用地址,实际值存于堆中

回收

一般有两种回收算法:引用计数、标记清除

引用计数

当给变量赋值时,会对值产生一次引用,把该值赋值给其他变量时,引用+1.

当对一个值产生引用的变量被销毁时,引用-1,直到引用数变成0,就可以回收掉

该算法有个问题是,循环引用会导致内存无法被回收,比如一个函数中两个对象互相引用,函数执行完,这两对象不会被回收,需要手动清除对象间的引用

标记清除

该算法运行时对所有变量标记为0

然后从全局对象开始往下访问,如果能访问到的变量就标记为1,之后标记为0的变量就会被清除

但这样会产生内存空隙,于是有个标记整理的算法来整理内存,让所有留存的对象向一端移动,然后清掉端边界以外的内存
image

v8

v8引擎采用分代收集的方式回收

  • 新生代 数据量小生命周期短的数据
  • 老生代 数据量大,生命周期长的数据

新生代采用复制算法来空间换时间,提高运行效率。分两个区,新加入的对象放入对象区,标记所有垃圾模块,其余模块顺序复制到空闲区,然后双方角色对调。如果一个对象经过多轮新生代回收还存在,就放入老生代。新生代是一块较小的空间

老生代采用标记清除+标记整理算法回收内存,回收频率较低

https://www.cnblogs.com/kaicy/p/14690488.html

内存碎片只会出现在堆中,因为栈只会随着闭包的不断执行而不断压栈执行上下文,执行完又会出栈,因此栈不存在复杂的垃圾回收机制,也不会出现碎片化

https://blog.csdn.net/Xu__Y/article/details/120813035

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions