当前位置: 首页 > news >正文

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

  • 原文地址:A crash course in memory management
  • 原文作者:Lin Clark
  • 译者:黑黑
  • 校对者:Bob

要理解为什么将 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前端高效开发实战》已在亚马逊、京东、当当开售。

相关文章:

  • 关于TRIM的优化技巧
  • 切换tab页
  • 哈希算法 加密算法
  • vuejs经验交流之-图片上传
  • 记一次Runtime Hook的问题
  • POJ 2942 圆桌骑士
  • 2016.3.17__CSS3动画__第十一天
  • 【搞机】9.7英寸iPad Pro 上手开箱(图文)
  • 【凯子哥带你夯实应用层】使用ActionProvider实现子菜单时遇到的一个坑
  • 使用 FreeRTOS 时注意事项总结(基础篇教程完结)
  • 推荐系统中的矩阵分解演变方式
  • Java——操作Excel表格,读取表格内容
  • 伊吹萃香
  • BZOJ 1878 SDOI2009 HH的项链 树状数组/莫队算法
  • 数据库对象
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 03Go 类型总结
  • CAP 一致性协议及应用解析
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • React组件设计模式(一)
  • SpiderData 2019年2月13日 DApp数据排行榜
  • 从PHP迁移至Golang - 基础篇
  • 计算机在识别图像时“看到”了什么?
  • 漂亮刷新控件-iOS
  • 入门级的git使用指北
  • 深度学习入门:10门免费线上课程推荐
  • 使用Swoole加速Laravel(正式环境中)
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 跳前端坑前,先看看这个!!
  • 用mpvue开发微信小程序
  • 在Mac OS X上安装 Ruby运行环境
  • 数据可视化之下发图实践
  • ​configparser --- 配置文件解析器​
  • #define
  • (C++17) optional的使用
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (SpringBoot)第七章:SpringBoot日志文件
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (四)鸿鹄云架构一服务注册中心
  • (万字长文)Spring的核心知识尽揽其中
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)大型网站架构演变和知识体系
  • (转载)Google Chrome调试JS
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .net Application的目录
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [].shift.call( arguments ) 和 [].slice.call( arguments )
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...