内存管理的速成课程

关于ECMAScript2017特性SharedArrayBuffer和atomics的背景知识:

本文分为三部分介绍

内存管理的速成课程

要理解为什么将ArrayBuffer和SharedArrayBuffer添加到JavaScript中,您需要了解一些有关内存管理的知识。

您可以将机器中的内存视为一堆盒子。我认为这些就像你在办公室里的邮箱,或学龄前儿童必须存放东西的小房间。

如果您需要为其他孩子留下一些东西,可以将它放在一个盒子里。

在这些框的每一个旁边,您都有一个数字,即内存地址。这就是你如何告诉别人在哪里找到你留给他们的东西。

这些盒子中的每一个都是相同的大小,可以容纳一定数量的信息。盒子的大小是机器特有的。该大小称为字大小。它通常类似于32位或64位。但是为了更容易显示,我将使用8位的字大小。

如果我们想将数字2放在其中一个框中,我们可以轻松完成。数字很容易用二进制表示。

如果我们想要一些不是数字的东西呢?喜欢字母H?

我们需要有办法将其表示为数字。为此,我们需要一种编码,如UTF-8。我们需要一些东西把它变成那个数字……就像一个编码器环。然后我们可以存储它。

当我们想要将它从包装盒中取出时,我们必须通过解码器将其转换回H.

自动内存管理
当你在JavaScript中工作时,你实际上并不需要考虑这个记忆。它被抽象出来了。这意味着您不要直接触摸内存。

相反,JS引擎充当中介。它为您管理内存。

所以让我们说一些JS代码,比如React,想要创建一个变量。

JS引擎所做的是通过编码器运行该值以获取值的二进制表示。

它会在内存中找到可以将二进制表示放入的空间。此过程称为分配内存。

然后,引擎将跟踪该变量是否仍可从程序中的任何位置访问。如果无法再访问该变量,则将回收内存,以便JS引擎可以在其中放置新值。

这个监视变量字符串,对象和其他类型值的过程在内存中进行,并在无法再访问它们时将其清除,称为垃圾回收。

JavaScript之类的语言(代码不直接处理内存)称为内存管理语言。

这种自动内存管理可以使开发人员更轻松。但它也增加了一些开销。而这种开销有时会使性能无法预测。

手动内存管理
手动管理内存的语言不同。例如,让我们看看如果React是用C语言编写的,React将如何处理内存(现在可以 使用WebAssembly)。

C没有JavaScript在内存上做的那个抽象层。相反,你直接在内存上运行。您可以从内存加载内容,并可以将内容存储到内存中。

当您将C或其他语言编译为WebAssembly时,您使用的工具会在WebAssembly中添加一些帮助程序代码。例如,它将添加执行编码和解码字节的代码。此代码称为运行时环境。运行时环境将帮助处理JS引擎为JS所做的一些事情。

但对于手动管理的语言,该运行时将不包括垃圾收集。

这并不意味着你完全依靠自己。即使在具有手动内存管理的语言中,您通常也会从语言运行时获得一些帮助。例如,在C中,运行时将跟踪在称为空闲列表的内容中打开的内存地址。

您可以使用该函数malloc(内存分配的简称)来要求运行时查找一些适合您数据的内存地址。这将从免费列表中取出这些地址。当您完成该数据后,您必须调用free以释放内存。然后这些地址将被添加回空闲列表。

你必须弄清楚何时调用这些功能。这就是为什么它被称为手动内存管理 - 你自己管理内存。

作为开发人员,弄清楚何时清除内存的不同部分可能很困难。如果你在错误的时间进行,它可能会导致错误,甚至导致安全漏洞。如果你不这样做,你的内存就会耗尽。

这就是许多现代语言使用自动内存管理的原因 - 以避免人为错误。但这是以牺牲性能为代价的。我将在下一部分中详细解释这一点。