【问题标题】:Node.js sliced string memoryNode.js 切片字符串内存
【发布时间】:2019-09-30 23:53:48
【问题描述】:

我是trying

r = [];
for (i = 0; i < 1e3; i++) {
    a = (i+'').repeat(1e6);
    r[i] = a.slice(64, 128);
}

并获得了 OutOfMemory。从here我们看到这是因为所有的as都保存在GC中,因为其中一部分被使用了。

  1. 如何让slice不留内存?我试过r[i]=''+a.slice(64, 128)+'',但仍然OOM。我必须a[64]+...+a[127](循环也算暴力)吗?
  2. 切割并只保留旧的大字符串的必要部分有这么难吗? problem here 只提到“将每个子字符串复制为新字符串”,而不是“释放部分字符串,保留必要部分可评估”

【问题讨论】:

    标签: node.js string garbage-collection


    【解决方案1】:
    1. 在这种情况下,应用程序代码应该更加了解系统约束:
    const r = [];
    for (let i = 0; i < 1e3; ++i) {
      const unitStr = String(i);
      // choose something other than "1e6" here:
      const maxRepeats = Math.ceil(128 / unitStr.length); // limit the size of the new string
      // only using the last 64 characters...
      r[i] = unitStr.repeat(maxRepeats).slice(64, 128);
    }
    

    ...应用程序的改进是:在每个输出字符串只需要 64 个字节的情况下,不再构造 1000 个最多 3,000,000 个字节的字符串。

    1. 未指定您的硬件和其他限制,但有时允许程序更多内存是合适的:
    node --max-old-space-size=8192 my-script.js
    
    1. 一种分析方法。使用逻辑更精确地确定每个工作数据块所需的内存状态。在提供的约束条件下,尽量减少不需要的内存中字符串数据的生成。
    const r = new Array(1e3).fill().map((e,i) => outputRepeats(i));
    
    function outputRepeats(idx) {
      const OUTPUT_LENGTH = 128 - 64;
      const unitStr = String(idx); // eg, '1', '40' or '286'
    
      // determine from which character to start output from "unitStr"
      const startIdxWithinUnit = (64 + 1) % unitStr.length;  // this can be further optimized for known ranges of the "idx" input
    
      // determine the approximate output string (may consume additional in-memory bytes: up to unitStr.length - 1)
      // this can be logically simplified by unconditionally using a few more bytes of memory and eliminating the second arithmetic term
      const maxOutputWindowStr = unitStr.repeat(Math.ceil(OUTPUT_LENGTH / unitStr.length) + Math.floor(Math.sign(startIdxWithinUnit)));
    
      // return the exact resulting string
      return maxOutputWindowStr.slice(startIdxWithinUnit, OUTPUT_LENGTH);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-11-27
      • 1970-01-01
      • 2014-07-21
      • 2012-02-15
      • 1970-01-01
      • 1970-01-01
      • 2020-12-31
      • 2022-11-11
      相关资源
      最近更新 更多