Pegjs: [问题] 关于 {cache: true} 和处理合理的内存不足情况的建议

创建于 2018-11-22  ·  3评论  ·  资料来源: pegjs/pegjs

问题类型

  • 问题:

先决条件

  • 你能重现这个问题吗?:是的
  • 您是否搜索了存储库问题?:是的,在 GitHub 问题中查看了cache ,在缓存中发现了一些问题,但不是我所要求的。
  • 你检查过论坛吗?:是的,试过googlegroups / cache ,没有相关结果
  • 您是否执行过网络搜索(谷歌、雅虎等)?:是的

描述

我正在使用大约 1000 行的语法解析一段相当重 (500KB) 的用户提供的文本。

  • 当传递{cache: true} ...

    • ...并告诉 Node 使用 3GB 的堆(使用--max-old-space-size=3000 ),堆增长到 2.5GB,并在 12 秒内解析成功。

    • ...并让 Node 10 默认为 800MB 的堆,解析崩溃并出现 OOM。

  • 当传递{cache: false} ,正如预期的那样,解析时钟在 10 秒(非病理情况)时稍微快一点,并且不会增加内存使用量。

这是用户数据,而我的服务器资源有限,因此无法让 Node 使用 X GB 的堆,因为明天我可能会获得 1MB 的用户数据,而这需要 X+1 GB 的堆。 当然,我想在可能的情况下继续使用{cache: true} ,以“避免病理情况下的指数解析时间” ,这是我遇到的。

你推荐什么方法?

  • 当内存使用变得至关重要时,PEG.js 中是否有任何内置的东西可以纾解?
  • 我用超时处理这个问题的尝试并不好,因为内存使用可能比超时增长得更快。
  • 据我所知,拦截节点 OOM 是不可能的。
  • 最后,我正在考虑根据输入的大小切换{cache: true}的用法。 这将花费我更多的 CPU 使用率,但至少我不会 OOM。
  • 其他想法?

感谢 PEG.js! 🙂

软件

  • PEG.js: 0.10.0
  • Node.js: 10.13.0
  • NPM 或纱线: npm 6.4.1
  • 浏览器:不适用
  • 操作系统: AWS Linux
performance question

所有3条评论

指数解析时间是在非常病态的情况下发生的事情,我建议在那里重写语法。
考虑https://github.com/sirthias/pegdown/issues/43#issuecomment -18469752
(我不是贡献者)

正如@polkovnikov-ph 指出的那样,最好重写处理病理情况的部分语法,但是如果您继续遇到 OOM 情况,那么按照您(@ronjouch)的建议进行操作可能会更好; 根据输入的大小切换 _cache_ 选项: cache: input.length >= 250000

在此之后(并且仅当您可以访问用户提供的文本时),我建议检查任何遇到 OOM 案例的输入以定位任何常见的病理案例并更新您的语法以明确处理这些,以便您可以减少 OOM 案例的数量打你的应用程序。

如果您仍然经常遇到 OOM 情况,并且愿意不仅重写您的语法,还愿意为您的工具链添加一个额外的(或几个)通过,我建议您尝试以下任何一种方法:

  • 拆分大输入,并更新您的语法以处理您正在解析的语法的部分部分,然后当所有输入部分都被解析后,加入所有内容(这很可能只有在您生成的解析器返回 AST 时才可行,否则不确定)
  • 使用正则表达式来识别用户提供的文本中可能导致病理情况的语法,然后再将其发送到 2 个生成的解析器之一:一个正常的解析器,另一个处理病理情况
  • 您始终可以使用 PEG.js 语法来生成一个行为类似于标记器的解析器,并构建一个可以优化解析正常输入和包含可能导致病理情况的语法的输入的解析器(需要您投入更多时间)学习解析器,有点违背解析器生成器的目的,但如果你知道你在做什么,_几乎总是一个可行的选择_)

@polkovnikov-ph @futagoza感谢你们两人抽出时间回来提出建议👍! 这就说得通了。 我部署了大小解决方法,下次麻烦敲门时会考虑重写语法。 再会; 结束问题。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

alanmimms picture alanmimms  ·  10评论

dmajda picture dmajda  ·  20评论

StoneCypher picture StoneCypher  ·  8评论

dmajda picture dmajda  ·  7评论

dmajda picture dmajda  ·  15评论