跳到主要内容

内存控制

2024年04月07日
柏拉文
越努力,越幸运

一、认识


JavaScript 中的内存问题内存问题至关重要,因为通过内存而造成的问题很容易被用户察觉。总的来说,内存问题可以定义为下面这三类:

  • 内存泄漏 (Memory leak)它会导致页面的性能越来越差
  • 内存膨胀 (Memory bloat),它会导致页面的性能会一直很差
  • 频繁垃圾回收,它会导致页面出现延迟或者经常暂停

二、内存泄漏


内存泄漏 当进程不再需要某些内存的时候,这些不再被需要的内存依然没有被进程回收。在 JavaScript 中,造成**内存泄漏 (Memory leak)**的主要原因是不再需要 (没有作用) 的内存数据依然被其他对象引用着。

2.1 操作

引起内存泄漏的操作有哪些?

  • 全局变量引起
  • 闭包引起
  • dom清空
  • 事件未清除
  • 子元素存在引用
  • 未清除的计时器

2.2 表现

Preview

如图所示: 内存泄漏是内存一直在缓慢增长

2.3 措施

三、内存膨胀


内存膨胀内存泄漏有一些差异,内存膨胀主要表现在程序员对内存管理的不科学,比如只需要 50M 内存就可以搞定的,有些程序员却花费了 500M 内存。额外使用过多的内存有可能是没有充分地利用好缓存,也有可能加载了一些不必要的资源。通常表现为内存在某一段时间内快速增长,然后达到一个平稳的峰值继续运行

3.1 表现

Preview

如图所示: 内存膨胀是快速增长,然后达到一个平衡的位置

3.2 措施

要避免内存膨胀,我们需要合理规划项目充分利用缓存等技术来减轻项目中不必要的内存占用。

四、频繁的垃圾回收


频繁使用大的临时变量,导致了新生代空间很快被装满,从而频繁触发垃圾回收。频繁的垃圾回收操作会让你感觉到页面卡顿

4.1 表现

function strToArray(str) { 
let i = 0
const len = str.length
let arr = new Uint16Array(str.length)
for (; i < len; ++i) {
arr[i] = str.charCodeAt(i)
}
return arr;
}
function foo() {
let i = 0
let str = 'test V8 GC'
while (i++ < 1e5) {
strToArray(str);
}
}
foo()

这段代码就会频繁创建临时变量,这种方式很快就会造成新生代内存内装满,从而频繁触发垃圾回收。

4.2 措施

为了解决频繁的垃圾回收的问题,你可以考虑将这些临时变量设置为全局变量