翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)

本文介绍了内存管理的基础概念,包括自动内存管理和手动内存管理的区别。详细解释了JavaScript如何处理内存分配和垃圾回收,以及C语言中如何手动管理内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要理解为什么将 ArrayBuffer 和 SharedArrayBuffer 添加到 JavaScript 中,你需要了解一些关于内存管理的内容。

你可以将机器中的内存看作一堆盒子。就像你在办公室里的邮箱,或是小孩子们使用的收纳箱。

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

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

这些盒子中的每一个都具有相同的尺寸,并且可以容纳一定量的信息。盒子的尺寸取决于机器。这个大小称为字长。它通常是32位或64位。但是为了显示方便,这里我们使用8位字长。

如果我们想把数字2放在其中一个盒子中,我们可以很容易地做到这一点。数字很容易转换成二进制

如果我们想要的东西不是数字怎么办?比如字母 H?

我们需要一个类似UTF-8的编码来用数字代替这些东西。而为了把这些东西转换成数字,我们需要一个类似编码器环的工具。之后我们就可以存储它了。

当我们想把它从盒子里拿出来的时候,必须通过解码器把它转换回 H。

自动内存管理

当你在使用 JavaScript 时,实际上并不需要考虑内存。内存被抽象出来,你不会直接接触到它。

取而代之的是 JS 引擎充当中介,为你管理内存。

比如说有一段 JS 代码用来创建一个变量(假设该 JS 代码使用了 React)。

JS 引擎利用编码器把该值转换成二进制。

它将在内存中找到可以容纳该二进制的空间,这个过程称为分配内存。

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

这种在内存中监控变量(字符串、对象或其他类型)并释放掉不再使用的变量所占用的内存的过程,称为垃圾回收。

像 JavaScript 这样不直接处理内存的语言被称为内存管理语言。

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

手动内存管理

和自动管理内存的语言相比,需要手动管理内存的语言有些不同。例如,我们来看看 React 如何使用 C 语言写入内存(现在可以通过WebAssembly实现)。

C 语言没有 JavaScript 在内存上的抽象层。而是直接在内存上运行。你可以从内存加载东西,也可以将内容存储到内存中。

当你将 C 语言或其他语言编译到 WebAssembly 时,你使用的工具将在 WebAssembly 中添加一些辅助代码。例如,它会添加用于编码和解码字节的代码。这些代码称为运行环境。运行环境会处理一些本该 JS 引擎做的事情。

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

这并不意味着你完全要自己处理。即使在手动内存管理的语言中,通常会从语言运行时获得一些帮助。例如,在 C 语言中,运行时会把哪些内存地址可用记录在一张表中,这张表叫做空闲列表。

你可以使用函数 malloc (内存分配的简写)来申请一些可以容纳数据的内存地址。这将把这些地址从空闲列表中拿走。当你处理完这些数据后,你须调用函数 free 释放掉由 malloc 函数申请的内存。之后,这些地址将被添加回空闲列表。

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

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

这就是为什么许多现代语言使用自动内存管理的原因——避免人为错误。但这是以性能为代价的。 我将在下一篇文章中更多地解释这一点。

iKcamp原创新书《移动Web前端高效开发实战》已在亚马逊、京东、当当开售。

### 如何根据角色和时间顺序的表格信息绘制 UML 顺序图 UML 顺序图是一种交互图,用于展示对象之间消息传递的时间顺序以及它们之间的关系。以下是关于如何基于角色和时间顺序的信息生成顺序图的具体方法。 #### 数据准备阶段 在开始绘图之前,需要整理好以下数据: - **参与者列表**:明确系统中的各个角色或对象[^1]。 - **事件序列**:按照时间顺序记录下这些角色之间的交互行为及其对应的输入输出参数[^2]。 #### 图形元素定义 顺序图主要由以下几个部分组成: 1. **生命线(Lifeline)** 表示参与交互的对象或者类实例的一条垂直虚线,在顶部标注名称并用冒号分隔其类型(如果已知)。例如 `:Customer` 或者 `Alice : User`。 2. **激活期(Activation Bar)** 当某个对象正在执行操作时,则在其生命线上方画出水平矩形区域作为激活标志;结束之后再关闭这个矩形框表示完成当前处理过程[^3]。 3. **消息(Message)** 使用有标签的消息箭头连接发送方与接收方的生命线,表明两者间存在通信联系。同步调用通常采用实心三角箭头指向目标端点,而异步通知则可能显示为空白尖角形式。 4. **返回值(Return Value)** 如果有必要指出函数调用的结果是什么样的话,可以在相应位置附加一条反向的小型虚线代表回传的数据流方向。 #### 绘制步骤说明 假设有一个简单的场景——在线购物车结算功能: | 时间 | 发起者 | 动作 | 接收者 | |------|--------------|-------------------------|-------------| | T1 | 用户 | 添加商品到购物车 | 购物车服务 | | T2 | 购物车服务 | 查询库存状态 | 库存管理模块| 转换为顺序图如下所示: ```plaintext User ->> Shopping Cart Service: Add Item to Cart(T1) Shopping Cart Service->>Inventory Management Module: Check Stock Availability (T2) ... ``` 通过以上方式可以清晰地展现整个业务逻辑链条上的每一步骤及时刻关联情况[^1]。 ### 示例代码片段 这里提供一段伪代码样例帮助理解构建流程: ```python class SequenceDiagramBuilder: def __init__(self, participants): self.participants = participants def add_message(self, sender, receiver, message_text, timestamp=None): pass # 实现具体逻辑 builder = SequenceDiagramBuilder(["User", "ShoppingCartService"]) builder.add_message("User","ShoppingCartService","AddItemToCart","T1") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值