Javascript对象和内存消耗

A while ago I read an article on different object creation patterns in Javascript. This article described how different patterns could consume more memory than others, and after reading it I wanted to build something to demonstrate what I had learned. I want to learn how to measure memory consumption in the browser, and I wanted to build something that would have a direct effect on my page’s memory consumption so that I could reliably demonstrate the negative effects of poorly written code.

不久前,我读了一篇有关Javascript中不同对象创建模式的文章。 本文描述了不同的模式如何比其他模式消耗更多的内存,阅读完之后,我想构建一些东西来证明我学到的东西。 我想学习如何在浏览器中测量内存消耗,并且想构建一些对页面内存消耗有直接影响的东西,以便我可以可靠地证明编写不良代码的负面影响。

在Chrome中测量内存使用情况 (Measuring Memory Usage in Chrome)

In the Chrome dev tools, there is a Memory tab. Here you can take a snapshot of the JavaScript VM’s heap and see how much memory is being used by your page. There are more complex options for looking at memory consumption over time which is useful for identifying code that is using a lot of memory, but for this all we need is the Heap snapshot tool.

在Chrome开发者工具中,有一个“内存”标签。 在这里,您可以拍摄JavaScript VM堆的快照,并查看页面正在使用多少内存。 有更多复杂的选项可用于查看一段时间内的内存使用情况,这对于识别使用大量内存的代码很有用,但是为此,我们需要的是堆快照工具。

So, in Chrome, open up the dev tools now and click on the Memory tab:

因此,在Chrome中,立即打开开发工具,然后单击“内存”标签:

Image for post

Heap snapshot should already be selected, so click Take snapshot at the bottom. Medium’s post editor is using 11.5 MB of memory:

堆快照应该已经被选中,因此请单击底部的“ 拍摄快照 ”。 中号的帖子编辑器正在使用11.5 MB的内存:

Image for post

垃圾邮件消耗内存 (Spamming Objects to Consume Memory)

To demonstrate some things we need a way to eat memory, so here is our contrived example!

为了演示一些事情,我们需要一种消耗内存的方法,因此这是我们精心设计的示例!

Image for post
a 10,000-strong square dance
10,000人的广场舞

Head on over to https://memorydots.netlify.app/ to see the above in action and to follow along with the examples.

转到https://memorydots.netlify.app/,以查看上面的内容并跟随示例。

The code spawns a 5x5 square at a random position within the bounds of the canvas, then each dot calls a function every frame that moves it in a random direction. The color of each dot is based on its position which has no relation to the topic at hand; it was just really boring when all the dots were one color.

该代码在画布边界内的任意位置生成一个5x5的正方形,然后每个点都会在向随机方向移动的每一帧调用一个函数。 每个点的颜色取决于其位置,该位置与当前主题无关。 当所有的点都是一种颜色时,真的很无聊。

那么我们正在测试什么? (So What Are We Testing?)

We’re going to be creating many dots using different implementations to show how these implementations consume different amounts of memory. So, here is a very simple dot:

我们将使用不同的实现方式创建许多点,以说明这些实现方式如何消耗不同的内存量。 因此,这是一个非常简单的点:

There’s not much going on here. The dot generates a starting position, and updatePosition moves it slightly while constraining it to the bounds of the canvas. The code could be simplified, but we’re trying to be wasteful here so let’s put on our cowboy hats and see how much memory these bad boys take up.

这里没有太多的事情。 点生成一个起始位置,并且updatePosition将其稍微移动,同时将其约束到画布的边界。 代码可以简化,但是在这里我们要浪费很多,因此让我们戴上牛仔帽,看看这些坏男孩占用了多少内存。

Back over to https://memorydots.netlify.app/, if we type 100000 into the Number of Dots text box and hit Create Simple then if your computer is anything like my laptop things will start to get a bit sluggish.

返回到https://memorydots.netlify.app/ ,如果在Number of Dots文本框中键入100000并单击“ Create Simple则如果您的计算机像我的笔记本电脑一样,东西将开始变得缓慢。

If we take a snapshot of the heap now, we can see how much memory our 100,000 dots are taking up:

如果现在对堆进行快照,则可以看到100,000个点占用了多少内存:

Image for post

13.3 MB. An exorbitant amount of memory. Let’s see if we can leverage the power of inheritance to lower this to a more reasonable amount.

13.3兆字节 大量的内存。 让我们看看是否可以利用继承功能将其降低到更合理的数量。

Javascript原型和继承 (Javascript Prototypes and Inheritance)

Behold, the same code in a slightly different shape:

看一下,相同的代码的形状略有不同:

Here we have a function, InheritDot, that when run creates a randomized starting position for itself. It then adds the updatePosition function to its prototype instead of containing it itself. All instances of InheritDot will inherit from the same prototype object, meaning that updatePosition will only exist once regardless of how many dots we make.

这里我们有一个函数InheritDot,该函数在运行时会为其自身创建一个随机的起始位置。 然后,将updatePosition函数添加到其原型中,而不是将其自身包含在内。 InheritDot的所有实例都将从同一个原型对象继承,这意味着无论我们创建多少个点, updatePosition都将仅存在一次。

Let’s take a look at the memory consumption of 100,000 Inherit Dots. If you’re following along on https://memorydots.netlify.app/, set the count to 100000, click Create Inherit and you should see something like this:

让我们看一下100,000个继承点的内存消耗。 如果您继续浏览https://memorydots.netlify.app/ ,将计数设置为100000,请单击“ Create Inherit ,您应该看到类似以下内容:

Image for post

By Grabthar’s Hammer, what a savings! At 7.7 MB we’re using 42% less memory to achieve exactly the same thing.

用Grabthar的锤子,真是节省! 在7.7 MB时,我们使用的内存减少了42%,以实现完全相同的操作。

A side note: We could have improved the Simple Dot by converting updatePosition into a separate module and importing it in like so:

旁注:我们可以通过将updatePosition转换为单独的模块并以如下方式导入它来改进简单点:

import random from 'lodash.random';
import updatePosition from 'modules/updatePosition';
function SimpleDot(ctx) {
this.x = random(0, ctx.canvas.width);
this.y = random(0, ctx.canvas.height);
this.updatePosition = updatePosition;
}
export default SimpleDot;

It’s still storing a reference to updatePosition for each dot, but at 100,000 dots I was seeing it take memory consumption from the 7.7 MB of the Inherit Dot to 8.1 MB. Much better than 13.3 MB, but it’s worth remembering that even references can take up space.

它仍然为每个点存储对updatePosition的引用,但是在100,000个点处,我看到它将内存消耗从“继承点”的7.7 MB减少到8.1 MB。 比13.3 MB好得多,但值得记住的是,即使引用也可能占用空间。

JavaScript类 (JavaScript Classes)

Controversial to some yet existing regardless, the class keyword brings JavaScript kicking and screaming into the 1960s.

无论是否存在争议, class关键字都将JavaScript带入1960年代。

Here is one of our dots implemented in a more Object-Oriented fashion:

这是我们以面向对象的方式实现的点之一:

We have the class Dot with an update function and a class ClassDot which extends Dot and is only responsible for its initial position. Essentially the same as Inherit Dot, but how does it stack up in memory consumption? On https://memorydots.netlify.app/ make sure the dot count is still 100000 and hit the Create Classbutton:

我们拥有带有更新功能的Dot类和扩展了Dot且仅负责其初始位置的ClassDot类。 本质上与Inherit Dot相同,但是它如何占用内存? 在https://memorydots.netlify.app/上,确保点数仍为100000然后单击“ Create Class按钮:

Image for post

Identical. When we have a peek under the hood, we can see why:

相同。 当我们在内部进行窥视时,我们可以看到原因:

Image for post

Both InheritDot and ClassDot have updatePosition in their prototype chain. Classes in JavaScript are a fancy wrapper around regular prototypical inheritance so fundamentally nothing has changed compared to the InheritDot.

InheritDotClassDot的原型链中都具有updatePosition。 JavaScript中的类是常规原型继承的奇特包装,因此与InheritDot相比,从根本上来说没有任何变化。

Neato! (Neato!)

Yeah! Now you know how to look at memory usage in Chrome, how to write some deliberately wasteful code, and how important it can be to understand what JavaScript is doing under the hood.

是的 现在,您知道了如何查看Chrome中的内存使用情况,如何编写一些故意浪费的代码,以及了解JavaScript到底在做什么的重要性。

The source for the MemoryDots example is available here: https://github.com/terrarum/memorydots

可在此处找到MemoryDots示例的源代码: https : //github.com/terrarum/memorydots

翻译自: https://medium.com/7factor/javascript-objects-and-memory-consumption-a3dae9c15fce

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值