Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

javascript内存分配 #89

Open
FrankKai opened this issue Aug 23, 2018 · 1 comment
Open

javascript内存分配 #89

FrankKai opened this issue Aug 23, 2018 · 1 comment

Comments

@FrankKai
Copy link
Owner

FrankKai commented Aug 23, 2018

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

  • javascript是如何做内存管理的?
  • javascript会对number类型做优化吗,会不会动态分配内存空间?
@FrankKai FrankKai changed the title javascript javascript内存分配 Aug 23, 2018
@FrankKai
Copy link
Owner Author

FrankKai commented Aug 23, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant