FrankKai / FrankKai.github.io

FE blog
https://frankkai.github.io/
363 stars 39 forks source link

javascript内存分配 #89

Open FrankKai opened 6 years ago

FrankKai commented 6 years ago

强类型语言对于数值类型,会做出非常多的划分,这样做的目的是更高效的使用有限的内存,但是javascript只有一种number数据类型,而且默认为float64位。由此引申2个问题。

FrankKai commented 6 years ago

Memory Management

介绍

对于底层语言,例如C语言,有非常底层的内存管理接口,例如malloc()和free()。但是另一方面,JavaScript值会在对象,字符串等创建的时候分配,并且在不使用时“自动地”释放。后者这种自动释放,准确来说叫做garbage collection。这种“自动地”(释放)会给JavaScript开发者一种错觉:我们不用主动去关心内存管理的问题。但是实际上,这是一种错误的认识!

内存生命周期

无论是什么编程语言,内存生命周期都是相同地:

  1. 分配需要的内存
  2. 使用分配来的内存(read,write)
  3. 不需要时释放内存

简单而言,可以精简为“拿 用 扔”,可以类比成“过河拆桥”。

  1. 分配需要的内存(搭桥)
  2. 使用分配来的内存(read,write)(过桥)
  3. 不需要时释放内存(拆桥)

这种“过河拆桥”式地做法,在军事上是很常见的,例如军队搭建起来的浮桥,用完即拆,这样会保证资源得到最大化的利用。但是如果对于使用频繁的大桥,例如跨海大桥,这种资源的占用就是必须的,需要建立的是长连接,不到万不得已,不会轻易去销毁。

在编程语言中,第2部分是明确的。第1和第3部分在底层语言中也是很明确的。但是在大多数类似javascript的高级编程语言中是不明确的。

内存分配和内存释放隐式利弊

好处

JavaScript中分配内存

值初始化

为了让开发者原理内存分配的困扰,JavaScript在声明变量时就自动分配了。

var n = 123; // 为一个number分配了内存
var s = "azerty"; // 为一个string配了内存

var o = {
    a: 1,
    b: null,
};// 为对象及其容纳的值分配了内存

// (类似对象)为数组及其容纳的值分配了内存
var a = [1, null, 'abra'];

function f(a) {
    return a + 2;
}// 为函数分配内存(这是一个可以被调用的对象)

//  函数表达式同样分配一个对象
someElement.addEventListener('click', function(){
    someElement.style.backgroundColor = 'blue';
}, false);

通过函数调用分配空间

一些函数调用会导致对象分配

var d = new Date(); // 分配一个Date对象
var e = document.createElement('div');// 分配了一个DOM元素

一些方法为新值或者对象分配:

var s = 'azerty';
var s2 = s.substr(0, 3);// s2是一个新的字符串
// 由于字符串是一成不变的值
// JavaScript偶尔也会不分配内存
// 仅仅存一个[0, 3]的范围

var a = ['ouais ouais', 'nan nan'];
var a2 = ['generation', 'nan nan'];
var a3 = a.concat(a2);
// 有4个元素的新数组,它是a和a2元素的串联

使用值(分配来的内存)

使用值意味着在已经分配的内存上读取或者写入。可以通过读写变量的值,读写对象的属性的值,甚至是给函数传递一个值,都属于使用值(分配来的内存)。

当内存不再被使用时进行释放

大多数内存管理问题都是在这一步出现。这里最困难的任务是找到那个点“分配好的内存不再使用”。它经常需要开发者决定在代码中决定哪一段不再需要并且释放它。

高等级的语言会自己嵌入一个软件片段,叫做“garbage collector”,它的工作就是追踪内存的分配和使用,从而决定什么情况下分配的内存不再被需要,不需要时会自动释放它。这个过程是一个概率事件,因为哪一个代码片段的内存在什么情况下是需要的并不可预测。(这是算法无法做到事情)

未完待续 参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management