JS 内存泄漏与垃圾回收机制

前言

不管什么程序语言,内存生命周期基本是一致的:

  1. 分配你所需要的内存
  2. 使用分配到的内存(读、写)
  3. 不需要时将其释放\归还

所有语言 第二部分都是明确的,第一和第三部分在 底层语言 中是明确的。但在像 JavaScript 这些高级语言中,大部分都是隐含的。

注意:JavaScript 是一种高级的解释执行的编程语言,是一种属于网络的高级脚本语言。

在 Chrome 浏览器中,V8 被限制了内存的使用(64位约1.4G/1464MB , 32位约0.7G/732MB),限制的主要原因是 V8 最初为浏览器而设计,不太可能遇到用大量内存的场景;更深层原因是 V8 垃圾回收机制的限制:清理大量的内存垃圾很耗时间,这样会引起 JavaScript 线程暂停执行,导致性能和应用直线下降。

JavaScript 是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时“自动”释放。 释放的过程称为垃圾回收。

这个“自动”是混乱的根源,并让 JavaScript 开发者错误的感觉他们可以不关心内存管理,进而引发内存泄漏。

一、什么是内存泄漏

程序的运行需要内存。只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存。

对于持续运行的服务进程,必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。

不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。

二、常见的内存泄漏

写得不好的JavaScript可能出现难以察觉且有害的内存泄漏问题。

在内存有限的设备上,或者在函数会被调用很多次的情况下,内存泄漏可能是个大问题。JavaScript中的内存泄漏大部分是由不合理的引用导致的。

下面来讲一讲常见的内存泄漏:

1. 意外声明的全局变量

意外声明全局变量是最常见但也最容易修复的内存泄漏问题。下面的代码没有使用任何关键字声明变量:

function setName() {
   
   
  name = 'yuanyuan';
}

此时,解释器会把变量 name 当作 window 的属性来创建(相当于 window.name = 'yuanyuan' )。可想而知,在 window 对象上创建的属性,只要 window 本身不被清理就不会消失。这个问题很容易解决,只要在变量声明前头加上 varletconst 关键字即可,这样变量就会在函数执行完毕后离开作用域。

2. 被遗忘的定时器

定时器也可能会悄悄地导致内存泄漏。下面的代码中,定时器的回调通过闭包引用了外部变量:

let name = 'yuanyuan'; 
setInterval(() => {
   
   
  console.log(name); 
}, 100);

只要定时器一直运行,回调函数中引用的 name 就会一直占用内存。垃圾回收程序当然知道这一点,因而就不会清理外部变量。

3. 使用不当的闭包

使用 JavaScript 闭包很容易在不知不觉间造成内存泄漏。请看下面的例子:

let outer = function() {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值