【问题标题】:Does JavaScript have a memory heap?JavaScript 有内存堆吗?
【发布时间】:2010-11-04 19:38:52
【问题描述】:

换句话说,在 JavaScript 中分配内存需要哪些选项?

我知道您可以在全局范围内或在函数范围内分配内存。我可以动态分配内存吗? new 运算符的真正含义是什么?

编辑:这是一个具体的例子。您将如何实现从用户读取整数值 - n,然后将 n 整数读取到数组中?

【问题讨论】:

  • 对于“特定示例”:只需 .push() 中的值。const n = read() 然后 const arr = []; for (let i = 0; i < n; i += 1) { arr.push(read()) }。 JS 中的“数组”是内存意识语言中的“向量”。
  • 对于以后看这个问题的人来说:对于像 JS 这样的语言,堆和堆栈不是该语言固有的,并且可能非常依赖于实现。 V8有堆和栈的分离,nullundefinedtruefalse虽然很原始,但实际上是分配在堆上的。这个答案stackoverflow.com/a/6604390/1460448 有更多细节。对于一个普通的 JS 程序员来说,虽然这更像是实现细节。

标签: javascript


【解决方案1】:

不,您不需要也不能分配内存。 JavaScript 解释器会自动执行此操作。

【讨论】:

  • 我不能同意这种说法。 var i = 0 是我所关心的所有内存分配。如果我不分配内存,我就不是在编程。
  • 所以您更想知道var 的用途以及为什么要使用它?
  • “内存分配”的内涵是指定你想要的字节数,分配它们(接收方式来引用分配的内存),然后把东西存在那里。由于 JScript 会为您处理所有这些,因此“内存分配”一词并不是一个好的名称选择。
【解决方案2】:

你不能分配内存。您可以创建对象。这就是new 所做的。

现在,javascript 是一个奇怪的生物:函数也是 javascript 中的对象。所以这意味着您可以使用new 实例化几乎所有内容。

所以,new 运算符意味着正在创建一个新对象。

Javascript 也会对这些变量进行垃圾收集,就像它发生在 java 中一样。所以如果你懂java,应该很容易比较吧。

干杯,

jrh

PS:当你分配对象时,你实际上是在分配内存。只是,您没有明确地这样做。您可以分配一个数组,并使其表现得像一个内存缓冲区,但这会大大降低 javascript 的性能:javascript 数组不是内存缓冲区,它们也是对象(就像其他所有东西一样)。

【讨论】:

    【解决方案3】:

    嗯,在我看来,您好像来自以记忆为中心的语言,并试图将这种逻辑硬塞到 JS 中。是的,JS 使用内存(当然),但我们有垃圾收集来负责清理它。

    如果您想了解内存分配的细节,那么您将不得不四处寻找。但作为一个规则经验,当你使用 var、new 或声明一个新函数(或闭包)时,你正在吞噬内存。您可以将 vars 设置为 null 以将它们标记为垃圾收集,并且您也可以使用 delete 关键字,尽管很少有人这样做,除非它们在服务器端工作(如我自己使用 ASP JScript),这很重要。

    【讨论】:

      【解决方案4】:

      JavaScript 具有垃圾收集功能并为您处理。

      但是,您可以在适当的情况下使用delete 运算符来帮助它。

      来自Apple JavaScript Coding Guidelines

      正如您使用 new 运算符 创建一个对象,你应该删除 完成后的对象 他们,像这样:

      delete myObjectVariable;

      JavaScript 运行时自动 垃圾收集对象时 值设置为空。但是,设置 为 null 的对象不会删除 引用对象的变量 从记忆里。使用 delete 确保 此内存被另外回收 到对象使用的内存 本身。 (也更容易看到 您的分配和 释放是不平衡的,如果你 显式调用删除。)

      史蒂夫

      【讨论】:

      • 我刚读到一篇文章说这是个坏主意:“在网上很多关于在 JavaScript 中回收内存的讨论中,都提到了 delete 关键字,好像它应该只用于从地图中删除键,一些开发人员认为您可以使用它强制取消引用。如果可以,请避免使用删除。更多详情,请转至goo.gl/2Abpe9 DE-REFERENCING MISCONCEPTIONS 部分
      【解决方案5】:

      Javascript 真的、真的很友好——真的、太友好了一半!

      如果您有一个包含 3 个元素的数组,并且想要添加第四个元素,您可以假设该数组位置已经存在:

          var arr = ['zero', 'one', 'two'];
          // Now you have arr[0], arr[1] and arr[2].
          // arr.length is equal to 3.
      .
          // to add arr[8]:
          arr[8] = 'eight';
          // Now you have arr[0] through arr[8]. arr.length is equal to 9.
          // and arr[3] through arr[7] exist, and 
          // are initialized to undefined. (If I remember right.)
      

      因此,在添加元素时,没有必要特别指定内存分配。

      【讨论】:

        【解决方案6】:

        回答问题的标题,如果你要信任MDN,大多数 JavaScript 实现都有一个堆:

        对象被分配在一个堆中,这只是一个表示大的名称 大部分是非结构化的内存区域。

        几个运行时一起通信

        网络工作者或跨域 iframe 有自己的堆栈、堆和 消息队列。两个不同的运行时只能通过 通过 postMessage 方法发送消息。这个方法增加了一个 如果后者侦听消息事件,则向其他运行时发送消息。

        要更深入地了解内存管理,还有一篇文章 here,尽管其中大部分内容是特定于实现的。

        【讨论】:

          【解决方案7】:

          您不需要在 Javascript 中手动管理内存。堆和堆栈都在后台用于管理内存,这取决于实现。通常,局部变量在栈上,对象在堆上。

          【讨论】:

            猜你喜欢
            • 2011-02-16
            • 2018-09-27
            • 2018-02-10
            • 2019-09-01
            • 1970-01-01
            • 1970-01-01
            • 2020-06-25
            • 2021-11-18
            • 2017-02-27
            相关资源
            最近更新 更多