内 存 管 理

57 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

说实话,是有点坚持不下去了的,下班回家后只想躺平。意志力渐渐被消磨,害。

今天知识点:内存分配与垃圾回收的工作原理,以及避免常见的内存泄漏。

正文:

在JS中,当我们创建变量、函数或者任何东西时,JS引擎都会为此分配内存,并在不再需要的时候释放它。分配内存:内存中空间被占用;释放内存:释放空间准备其他用途。

所以,每当创建变量或者函数时都大致如下步骤:

graph TD
分配内存 --> 使用-->释放

(哇掘金写文章的体验感好优秀,绘图都这么方便。)

ok,现在我们了解到JS会分配内存并在不再需要的时候释放内存。

此时我拿起了桌上的白巧克力吃了一大口,真!好!吃!好吃!!!!

那么思考问题:数据会被放在哪里。

答案:内存堆和堆栈。

堆栈:静态内存分配

堆栈是JS用来存储静态数据的。静态数据啊就是字符串 数字 布尔值 undefined null这些大小不会改变的数据。由于引擎知道大小不会改变,所以就为每个值分配一定数量的内存,即静态内存分配。

堆:动态内存的分配

堆在JS中存储对象 函数。与堆栈不同,引擎不会为这些对象分配固定数量的内存。相反,会根据你的需要分配更多的空间。即,动态内存分配。

例子:

const child ={
name:"小红",
age:18
}

JS在堆中为这个对象分配内存。都说const定义变量时不可改变,像被冻结,但像上一个例子中如果child.hobby="吃饭"也是可以的,不会报错的,因为当const一个对象时就分配了动态的地址,其指针指向的地址是不会改变的,但里面的内容在堆中可以改变。

例子:

const age = 18
如果把age改变的话是会报错的,因为是数字,JS把他初始就分配到堆栈中,是静态内存分配,值不可以被改变。

垃圾回收:

生命周期的末尾:释放内存。

垃圾收集器负责处理这个问题。一旦JS引擎识别出某个给定的变量或函数我们不再需要,那就会释放它所占用的内存。最常用的两种方法:引用计数和标记清除。

引用计数垃圾回收:

引用计数的含义就是跟踪记录每个值被引用的次数。但是貌似存在问题:

let son = {
name:'join'
}
let dad = {
name:"johnson",
}
son.dad = dad;
dad.son=son

son=null;
dad=null;

两个对象相互引用,所以不会释放分配的内存,即使设置成null该算法也无法意识到他们不可以再使用,因为一直都有值传入。

标记清除垃圾回收:

该算法将不可访问的对象标记为垃圾,然后对其进行清理。它解决了引用计数的循环弊端。

在son和dad示例中,使用引用计数存在bug.

标记清除本质是检测他们是否可以从根对象访问。在前面示例中不能从根访问son和dad,因此它们都将被标记为垃圾并回收。

内存泄漏:

常见的内存泄漏:定义全局变量,闭包的使用,定时器未销毁,以及一些回调函数。

` window.a=111

setInterval(function(){},1000) 记得clearInterval()

时间监听器:把Onclick监听到按钮中实现一些函数,记得removeEventListener删除它

`

写的好累,就这些吧,有错误请指出。

小熊一体锅 6 天。