在上一篇文章中,老司机带你了解了像 JavaScript 这样的语言是如何自动管理内存的。还解释了如何在 C 语言中手动管理内存。
我们为什么要在介绍 ArrayBuffers 和 SharedArrayBuffers 之前,先解释内存管理的知识呢?
这是因为,在 JavaScript 中,正是 ArrayBuffers 给你提供了手动管理内存的途径。
为什么要去手动管理内存呢?
正如我们在上一篇文章中谈到的关于自动内存管理的利弊:自动内存管理对开发人员来说比较友好。但它增加了一些额外的开销,在某些情况下,这些开销可能导致性能问题。
例如,当你在 JS 中创建变量时,引擎必须猜测它的数据类型,以及如何保存在内存中。因此,JS 引擎通常预留的空间比这个变量真正需要的空间大很多。根据变量的不同,内存分配可能会比实际需要的大2-8倍,这会导致大量的内存浪费。
此外, 某些创建和使用 JS 对象的模式会使收集垃圾变得更加困难。如果你手动管理内存的话, 可以根据实际使用需求来决定分配和释放内存的策略。
大多数时候, 这没什么大不了的。因为,大多数场景对性能要求并不苛刻,你无需手动管理内存。对于常见场景,手动内存管理甚至可能会更慢。
但是对于那些在底层需要极致优化的场景,ArrayBuffers 和 SharedArrayBuffers 就派上用场了。

那么 ArrayBuffer 怎么工作?

它基本上就像其它 JavaScript 数组一样。但是,ArrayBuffer 的元素必须是字节(可以用数字表示),对象或字符串这类的 JavaScript 类型的数据是不行的。
有一点我应该在这里明确指出,你并没有将这个字节直接添加到 ArrayBuffer 中。ArrayBuffer 本身并不知道字节应该有多大,也不知道不同的数字应该如何转换成字节。
ArrayBuffer 只是一串 0 和 1。它是不知道怎么拆分这个数组中各个元素的。
为了提供上下文信息,把 ArrayBuffer 拆分开,我们需要将它放在视图中。这些数据的视图可以添加类型化数组,并且有很多不同的类型数组可以使用。
例如,你可以使用 Int8 类型的数组,将 ArrayBuffer 分解为8位字节。
或者你可以用一个无符号的 Int16 类型数组,它可以将 ArrayBuffer 分解成16位不带符号整数。
同一 buffer 上可以有多个视图,不同的视图会为相同的操作提供不同的结果。
例如,我们从这个 ArrayBuffer 的 Int8 视图获取的元素,和从它的 Uint16 视图获取的元素就是不同的值,即使它们包含完全相同的 bits。
通过这种方式,ArrayBuffer 基本上就像原始内存,让你可以像使用 C 语言那样直接操作内存。
你可能会想知道为什么我们不让程序员直接访问内存,而是添加这一层抽象。这是因为直接访问内存将会打开一些安全漏洞。以后我会写一篇文章对此进行详细的解释。

那么 SharedArrayBuffer 是什么?

要解释 SharedArrayBuffers,我需要先解释一下并行运行代码和 JavaScript。
并行运行代码会使你的代码运行更快,也可以更快的响应用户的事件。要做到这一点,你需要先拆分工作。
在一个典型的应用中,所有工作全部单独由主线程来处理。主线程就像一个全栈开发者,它负责处理 JavaScript,Dom,和布局。
任何减少主线程工作负载的事对代码运行效率都是有帮助的。在某些情况下,ArrayBuffer 可以减少主线程的工作。
但有时仅仅减少主线程工作是不够的,你还需要一个增援来分担一部分工作。
大多数语言里,这种分割工作的方法可以使用多线程实现。这就像多人在一个项目上工作。如果有些任务是相互独立的且没有依赖,那么就可以把它们分配到不同线程上。然后,这些线程可以同时处理单独的任务。
在 JavaScript 中,可以通过 web worker 来实现这些,但跟其他语言中的线程处理方式有些不同。默认情况下,它们不共享内存。
这意味着,如果想处理一些其他线程上的数据,你不得不通过 postMessage 方法将数据完整的复制一份过来。
postMessage 会将你传进去的东西序列化,然后发送给另一个 web worker,那边会反序列化并放入内存中。
这是一个相当缓慢的过程。
对于某些数据,比如 ArrayBuffer,你还可以使用“转移内存”。这种方式会把指定区域的内存移动到另一个 web worker 那里。
但是之前的 web worker 将不再能访问这些被转移走的内存。
转移内存这种方式适用于某些场景,但是对于更多的高性能并行的场景,共享内存才是你真正想要的。
这就是 SharedArrayBuffers 能给你的。
有了 SharedArrayBuffers,多个 web workers,多个线程都可以在同一块内存上读写数据。
这意味着他们不会再有使用 postMessage 时的通讯开销和延迟。所有 web workers 都可以即时访问数据。
当然,多个线程同时访问内存是有风险的,这会引起条件竞争(race conditions)问题。
我会在下一篇中详细说明。
SharedArrayBuffers 的支持情况
SharedArrayBuffers 即将在所有主流浏览器中支持。
Safari 10.1 已经支持了,Firefox 和 Chrome 的版本 将在7月或8月发布。而 Edge 计划在秋季 Windows 的更新中得到支持。
即使所有主流浏览器都支持了,我们也不指望应用开发者们直接使用它们。事实上,我们也不推荐直接使用。你应该使用的是最顶部的抽象层。
我们希望 JavaScript 库的开发者们开发出更简单安全的使用 SharedArrayBuffers 的库。
此外,一旦 SharedArrayBuffers 内置到平台中,WebAssembly 可以利用它实现多线程。到那时,你就可以使用像 Rust 这种以处理并发性为目标的语言一样轻松的处理多线程。
下一章,我们将介绍那些库开发者们构建抽象同时又避免条件竞争(race conditions)所使用的工具 Atomics
 

看图学习 ArrayBuffers 和 SharedArrayBuffers的更多相关文章

  1. VS2017 community版使用码云(gitee)的一些过程,看图学习,傻瓜式教程

    首先你得有一个gitee账号,VS2017IDE开发工具 第一步,打开VS2017,点击菜单栏上->工具->扩展与更新,如图 然后点击 联机 然后输入 gitee 回车搜索 一定要选择我圈 ...

  2. (CV学习笔记)看图说话(Image Captioning)-1

    Background 分别使用CNN和LSTM对图像和文字进行处理: 将两个神经网络结合: 应用领域 图像搜索 安全 鉴黄 涉猎知识 数字图像处理 图像读取 图像缩放 图像数据纬度变换 自然语言处理 ...

  3. 学习笔记TF060:图像语音结合,看图说话

    斯坦福大学人工智能实验室李飞飞教授,实现人工智能3要素:语法(syntax).语义(semantics).推理(inference).语言.视觉.通过语法(语言语法解析.视觉三维结构解析)和语义(语言 ...

  4. 【转载】跟着9张思维导图学习JavaScript

    原文:跟着9张思维导图学习JavaScript 学习的道路就是要不断的总结归纳,好记性不如烂笔头,so,下面将 po 出我收集的 9 张 JavaScript相关的思维导图(非原创). 思维导图小ti ...

  5. Multimodal —— 看图说话(Image Caption)任务的论文笔记(一)评价指标和NIC模型

    看图说话(Image Caption)任务是结合CV和NLP两个领域的一种比较综合的任务,Image Caption模型的输入是一幅图像,输出是对该幅图像进行描述的一段文字.这项任务要求模型可以识别图 ...

  6. [看图说话]在VMware Workstation 9中安装Mac OS X 10.8 Mountain Lion

    本文环境: CPU:Intel Core i7 920: OS:Windows 7: 内存:8G: 玩Hackintosh各有各的理由,不管什么理由,利用虚拟机安装Mac OS X都是一个可行的办法. ...

  7. 跟着9张思维导图学习Javascript js 关键字和保留字 css3中的BFC,IFC,GFC和FFC

    跟着9张思维导图学习Javascript   学习的道路就是要不断的总结归纳,好记性不如烂笔头,so,下面将 po 出我收集的 9 张 javascript 相关的思维导图(非原创). 思维导图小ti ...

  8. 关于图计算&图学习的基础知识概览:前置知识点学习(Paddle Graph Learning (PGL))

    关于图计算&图学习的基础知识概览:前置知识点学习(Paddle Graph Learning (PGL)) 欢迎fork本项目原始链接:关于图计算&图学习的基础知识概览:前置知识点学习 ...

  9. 图学习【参考资料2】-知识补充与node2vec代码注解

    本项目参考: https://aistudio.baidu.com/aistudio/projectdetail/5012408?contributionType=1 *一.正题篇:DeepWalk. ...

随机推荐

  1. c# Attribute会不会影响性能

    Attribute很方便,标记一个类,设置这个类的额外信息,而不用另外设计存储这个信息. 那么频繁大量使用Attribute会不会影响类的性能. 为此,简单测试. 代码: 略............. ...

  2. 浏览器自动化的一些体会5 webBrowser控件之winform和webBrowser的交互

    从winform访问webBrowser,大致就是利用webBrowser提供的解析dom的方法以及用InvokeScript方法执行javascript.这个相对比较简单. 从webBrowser访 ...

  3. 土题大战Vol.0 A. 笨小猴 思维好题

    土题大战Vol.0 A. 笨小猴 思维好题 题目描述 驴蛋蛋有 \(2n + 1\) 张 \(4\) 星武器卡片,每张卡片上都有两个数字,第 \(i\) 张卡片上的两个数字分别是 \(A_i\) 与 ...

  4. 面试官最爱的 volatile 关键字,这些问题你都搞懂了没?

    前言 volatile相关的知识点,在面试过程中,属于基础问题,是必须要掌握的知识点,如果回答不上来会严重扣分的哦. volatile关键字基本介绍 volatile可以看成是synchronized ...

  5. CODING DevOps 微服务项目实战系列第二课来啦!

    近年来,工程项目的结构越来越复杂,需要接入合适的持续集成流水线形式,才能满足更多变的需求,那么如何优雅地使用 CI 能力提升生产效率呢?CODING DevOps 微服务项目实战系列第二课 <D ...

  6. DP搬运工1 [来自yyy--mengbier的预设型dp]

    DP搬运工1 题目描述 给你 \(n,K\) ,求有多少个 \(1\) 到 \(n\) 的排列,满足相邻两个数的 \(max\) 的和不超过 \(K\). 输入格式 一行两个整数 \(n,K\). 输 ...

  7. 随机陷阱和P值

    如果让大家写一个50次的抛硬币实验的可能结果(头像H或字T),多半人在连续三个一样的后,会换一下.因为大家都知道,连续一样的越多,概率越小,越不可能发生.大部分人不会去想,其实HHHTT和HHHHH发 ...

  8. idea git拉取、合并、处理冲突、提交代码具体操作

    早在两个月前我还在用eclipse开发,并且也发布的一些eclipse git的相关操作(操作都是本人亲自实践过的),但由于项目团队要求,开发工具统一用idea,实在不得已而为之切换了开发工具, 初次 ...

  9. 6. 二十不惑,ObjectMapper使用也不再迷惑

    一滴水,用显微镜看,也是一个大世界.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众 ...

  10. packmol建模流程-计算

    一.建模流程(modelling procedure): 1.美国数据库下载amc.cif文件:http://rruff.geo.arizona.edu/AMS/amcsd.php 2.导入vesta ...