「译」内存管理碰撞课程

做者:Lin Clark
译者:Cody Chan
原帖连接:A crash course in memory management

这是图解 SharedArrayBuffers 系列的第一篇:web

  1. 内存管理碰撞课程segmentfault

  2. 图解 ArrayBuffers 和 SharedArrayBuffers安全

  3. 用 Atomics 避免 SharedArrayBuffers 竞争条件函数

为了更好地理解 JavaScript 里的 ArrayBuffer 和 SharedArrayBuffer,首先应该了解点内存管理知识工具

你能够把一个机器的内存想成一个一个的盒子,我把它们看成办公室的邮箱或者幼儿园里放小孩东西的格子性能

若是你想把某个东西留给某个小孩,你就把东西放到格子里编码

每一个盒子旁边都有一个编号,这就是内存地址,用于告诉别人如何去找到你留的东西spa

每一个盒子大小都同样,能够存放特定容量东西。盒子的具体容量取决于机器,这个大小咱们称为字长,通常为 32 位或者 64 位。不过,为了展现方便,我这里字长用 8 位翻译

若是你想把数字 2 放到盒子里,这很容易作到,由于数字很容易用二进制表示3d

可是若是你想放一个非数字类型的呢?好比字母 H?

咱们须要一种方式能够用数字来表示它,这须要借助编码技术,相似 UTF-8 。首先,咱们须要一个东西能够把字母转为数字……相似一个编码环,接下来就能够存储了

当咱们从盒子里取回的时候,咱们须要把取出的数字放到解码环里翻译回字母 H

自动内存管理

若是你是写 JavaScript 的,实际上你根本不须要关心内存,它对用户是透明的,这意味着你没法直接操纵内存

与此相对的, JS 引擎扮演着中间人角色,它为你管理好内存

咱们用 React 举个例子,好比建立一个变量

JS 引擎经过一个编码器获得这个变量的二进制表示

而后,它会找到内存中能够放这个值的位置,这个过程称为内存分配

紧接着,引擎会持续追踪这个变量,看其是否还在程序中被使用。若是这个变量已经没有引用了,这块内存会被回收,JS 引擎就又能够在这里放新的值了

追踪内存中的变量(字符串、对象以及其它类型)而且在没有引用的时候清除它们的过程咱们称做垃圾回收

相似 JavaScript 这种代码没法直接处理内存的语言叫作自动内存管理(memory-managed)语言

内存自动管理确实让开发者省了很多心,可是这也会带来额外的开销,这些额外开销会让程序的性能没法评估

手动内存管理

手动内存管理的语言不太同样,继续上面例子,看 React 用 C 写的话(借助 WebAssembly可能的)会如何处理内存

不像 JavaScript,C 没有单独的内存管理抽象层,相反,你得直接与内存打交道。你能够从内存中直接拿东西,也能够直接往内存里存东西

当你把 C 或者其它语言编译为 WebAssembly 时,编译工具会在 WebAssembly 里增长一些辅助代码。好比,它会加入编解码的代码,这些代码咱们称为运行时环境,运行时环境会帮助处理一些相似 JS 引擎帮 JS 作的事

可是,对于手动管理内存的语言,运行时不会包括垃圾回收

这并不意味着你须要彻底由本身处理内存,即便在这类语言里,运行时你依然会获得一些辅助。好比,C 语言运行时会在一个 free list 里追踪能够使用的内存地址

你能够使用 malloc 函数(内存分配的简称)向运行时发出能够知足你数据存储须要的内存请求,这些内存会被从 free list 拿下来。当你用完了,须要调用 free 去释放内存,这些内存会被加回 free list

你必须清楚知道何时去调用这些函数,这就是为何咱们叫手动内存管理

做为一个开发者,知道何时去释放什么地方的内存是一件困难的事。若是你在错误时机处理了,这极可能会致使 BUG,甚至安全漏洞;若是你不处理,就会致使内存泄露

这就是为何不少语言选择自动内存管理去避免人为错误,可是这牺牲了性能,下篇文章我还会谈到这些

相关文章
相关标签/搜索