【问题标题】:Memory Usage Of Different Data Types in javascriptjavascript中不同数据类型的内存使用情况
【发布时间】:2011-06-21 19:24:59
【问题描述】:

发生在我身上的一个问题是javascript中不同的数据类型使用了多少内存。例如,在 C++ 数据类型中,如 int、char、float 使用顺序 2、1、8 字节的内存。现在数据类型,如数字、字符串、布尔值、空值、未定义和对象、javascript 中的数组使用了多少内存以及接受的范围是多少? 由于我的英语水平低,请接受我的道歉!!!

【问题讨论】:

  • 与 C 不同,在 JS 中,对于给定类型的值没有强制要求特定的内存布局,它取决于 JS 引擎,甚至取决于值的创建方式(例如,"literal string" 与连接其他字符串)。这里的答案集中在负载大小上,它可能在不同对象之间共享,不包括对象本身的开销(参见stackoverflow.com/a/45808835/1026stackoverflow.com/a/18975098/1026 示例)。

标签: javascript types


【解决方案1】:

数字是 8 个字节。

发现在这个w3schools page

我搜索了更多其他 JavaScript 原始类型,但很难找到这些信息!我确实找到了以下代码:

    ...
    if ( typeof value === 'boolean' ) {
        bytes += 4;
    }
    else if ( typeof value === 'string' ) {
        bytes += value.length * 2;
    }
    else if ( typeof value === 'number' ) {
        bytes += 8;
    }
    ...

似乎表明一个String是每个字符2个字节,而一个布尔值是4个字节。

找到代码herehere。完整代码实际上用于获取对象的粗略大小。

尽管在进一步阅读后,我在此页面上发现了 konijn 的这个有趣代码:Count byte length of string

function getByteCount( s )
{
  var count = 0, stringLength = s.length, i;
  s = String( s || "" );
  for( i = 0 ; i < stringLength ; i++ )
  {
    var partCount = encodeURI( s[i] ).split("%").length;
    count += partCount==1?1:partCount-1;
  }
  return count;
}
getByteCount("i♥js"); // 6 bytes
getByteCount("abcd"); // 4 bytes

所以看起来字符串在内存中的大小取决于字符本身。尽管我仍在试图弄清楚为什么他将计数设置为 1,如果它是 1,否则他会使用 count-1(在 for 循环中)。

如果我发现任何其他内容,将更新帖子。

【讨论】:

  • getByteCount 检测字符串的 url 编码版本中的 % 数,这是 UTF-8 编码所需的字节数。这与内存中的表示无关。
  • 4 个字节的布尔值 :D??
  • 但肯定一个空字符串不只占用0字节?
【解决方案2】:

截至今天,MDN Data Structures 页面提供了有关它的更多信息:

数字

根据 ECMAScript 标准,只有一种数字类型:双精度 64 位二进制格式 IEEE 754 值

所以应该是 8 个字节。

字符串

JavaScript 的 String 类型用于表示文本数据。它是一组 16 位无符号整数值的“元素”。

所以每个字符应该占 2 个字节。

布尔值

Boolean 表示一个逻辑实体,可以有两个值:true 和 false。

没什么好说的了。

【讨论】:

  • 问题:布尔值的定义不也告诉你答案吗?既然它要么开要么关,并且位要么是 1/0,那么布尔值不应该是 1 位吗?
  • 嗯,不,由于内存管理和寻址技术等原因,1 位足以存储布尔值这一事实并不意味着布尔值将以 1 位存储。至少在我学习计算机体系结构时:),一个字节是最小的可寻址内存量。参见例如this SO question求答案
  • @KitangaNday 实际上用 4 个字节 存储布尔值,请参阅接受的答案
  • @Adam 是的,我知道?。我很久以前就读过接受的答案。
  • @superjos 我在互联网上找到了this,我想它可能会回答为什么布尔值实际上是 4 个字节。
【解决方案3】:

一个值的内存表示,也就是它的大小,是一个实现细节,除非另有说明,并且可以根据运行时环境的底层代码而有所不同。运行时是运行 JavaScript 代码的应用程序,即 Nodejs、Firefox 浏览器或 Chrome 浏览器。

假设您编写自己的运行时并且想要表示一个布尔值。布尔值至少需要一位,因此您可以将其作为一位存储在内存中。

这是真的:

这是错误的:

但是没有什么能阻止你使用 8 位或 1 字节的内存空间。这里最高有效位保存值,其余将用 0 填充:

□□□□□□□■

或 64 位:

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□■

同样的事情也适用于字符串值。您可以使用 8 位或 64 位甚至更多位来表示它。然而,语言承诺对任何 Unicode 值进行操作,但 8 位可能不足以表示所有 Unicode 值。这就是您在规范中找到一些地址和调整的地方。 JavaScript 中的字符串被视为 UTF-16 代码单元的序列,一些字符占用 16 位内存空间,而另一些则占用 32 位。

代码单元是从 Unicode 规范借用的术语。您可能会问为什么不是字符而是代码单元,因为字符是表示特定文本数据的一种方式,还有其他方式。例如,é\u00E9\u{E9} 都创建带有锐角的字母 e。在您的 JavaScript 字符串中,您可以选择其中任何一个。

数学很棘手,因为在 CPU 级别上,所有计算都是以二进制完成的,而二进制不会毫无问题地转换为十进制。尝试运行 0.1 + 0.1 == 0.3。因此,我们需要更严格地控​​制准确性。这就是为什么规范对数字表示非常具体:双精度 64 位二进制格式 IEEE 754。

总而言之,在编写 JavaScript 运行时,如何在内存中存储值取决于您,除非规范中明确规定。这就是为什么一些数据类型在内存中应该如何表示和存储的问题上进行了冗长的讨论。

运行时环境通常是用 C、C++ 或 Rust 等较低级别的语言编写的,并且内存管理被委托给这些语言使用的内容。

如果你是 JavaScript 程序员,你不需要关心内存是如何分配和释放的,因为运行时会为我们处理这部分。您唯一可能遇到的问题是循环引用导致的内存泄漏:对象 A 引用了对象 B,而对象 B 引用了对象 A。开发人员控制台中有一些工具可以检测此类问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 2017-05-31
    • 2013-01-14
    • 2015-01-08
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多