通过 es.map() 和 JSONStream.stringify() 将 JSONStream.parsed() 数据传输到文件流时,节点堆耗尽

2024-03-24

我正在尝试通过 JSONStream.parse() 通过管道传输输入流(从巨大的 GeoJSON 文件创建)以将流分解为对象,然后通过 event-stream.map() 以允许我转换对象,然后通过 JSONStream .stringify() 创建一个字符串,最后创建一个可写的输出流。随着进程的运行,我可以看到节点的内存占用量继续增长,直到最终耗尽堆。这是重现问题的最简单的脚本 (test.js):

const fs = require("fs")
const es = require("event-stream")
const js = require("JSONStream")

out = fs.createWriteStream("/dev/null")
process.stdin
    .pipe(js.parse("features.*"))
    .pipe(es.map( function(data, cb) { 
        cb(null, data);
        return;
    } ))
    .pipe(js.stringify("{\n\"type\": \"FeatureCollection\", \"features\": [\n\t", ",\n\t", "\n]\n}"))
    .pipe(out)

一个小 bash 脚本(barf.sh)将无尽的 JSON 流注入节点的 process.stdin 中,这将导致节点的堆逐渐增长:

#!/bin/bash

echo '{"type":"FeatureCollection","features":['
while :
do
    echo '{"type":"Feature","properties":{"name":"A Street"}, "geometry":{"type":"LineString"} },'
done

通过这样运行它:

barf.sh | node test.js

有几种奇怪的方法可以回避这个问题:

  • 删除 fs.createWriteStream() 并将最后一个管道阶段从“.pipe(out)”更改为“.pipe(process.stdout)”,然后将管道节点的 stdout 更改为 /dev/null
  • 将异步 es.map() 更改为同步 es.mapSync()

前面两个操作中的任何一个都将允许脚本永远运行,节点的内存占用量较低且不变。我在运行 Ubuntu 16.04、具有 8GB RAM 的八核机器上使用 Node v6.3.1、event-stream v3.3.4 和 JSONStream 1.1.4。

我希望有人能帮助我纠正我确信是我的明显错误。


JSONStream 不是streams2流,所以不支持背压控制。 (有一个简短的总结streams2 here https://gist.github.com/caike/ebccc95bd46f5fa1404d.)

这意味着数据将从parse流入data事件,并且无论消费流是否准备好它们,流都会继续将它们泵出。如果管道中某处的读取和写入速度之间存在差异,就会出现缓冲 - 这就是您所看到的。

Your barf.sh线束看到通过注入的功能stdin。相反,如果您正在读取大量文件,则应该能够通过暂停文件的读取流来管理流程。所以如果你要插入一些pause/resume逻辑到你的map回调,你应该能够让它处理一个大文件;只是需要更长的时间。我会尝试这样的事情:

let in = fs.createReadStream("/some/massive/file");
let out = fs.createWriteStream("/dev/null");
in
    .pipe(js.parse("features.*"))
    .pipe(es.map(function(data, cb) {
        // This is just an example; a 10-millisecond wait per feature would be very slow.
        if (!in.isPaused()) {
            in.pause();
            global.setTimeout(function () { in.resume(); }, 10);
        }
        cb(null, data);
        return;
    }))
    .pipe(js.stringify("{\n\"type\": \"FeatureCollection\", \"features\": [\n\t", ",\n\t", "\n]\n}"))
    .pipe(out);

顺便说一下,使用mapSync在我的计算机上几乎没有什么区别(它又旧又慢)。但是,除非您要执行一些异步操作map,我会选择mapSync.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 es.map() 和 JSONStream.stringify() 将 JSONStream.parsed() 数据传输到文件流时,节点堆耗尽 的相关文章

随机推荐

  • EXC_BAD_ACCESS 在带有参数的本地化字符串上崩溃

    这里遇到了一个只出现在某些手机上的奇怪问题 我有一个自定义的 UIView 我像这样初始化 let passQuizToTutorAlert SAAlertView title NSLocalizedString quiz title co
  • Laravel 符号链接和 cPanel

    在我的 Laravel 网站上 我使用符号链接来存储和显示存储中的图像 With php artisan storage link 我创建了符号链接 每次上传新新闻文章时 图像都会上传到主存储中 并使用符号链接将其设置到公共文件夹中 并且我
  • 如何将 WAMP 本地主机从 Firefox 移至 chrome?

    我最近在计算机上安装了 WAMP 服务器 当我打开 localhost 时 它会自动在 Firefox 中打开 我希望它在 Chrome 中打开 以便我可以使用 Chrome 开发人员工具 如何让我的本地主机在 chrome 而不是 fir
  • JavaScript if 语句的行为不符合预期

    刚刚学习 JavaScript 代码 尝试学习 if 语句 但我的代码不起作用 var car 8 if car 9 document write your code is not working 这会执行写入命令 我不知道为什么 我使用制
  • 如何在水平回收器视图上滑动仅将下一个项目带入视图 - Android

    我有一个水平的RecyclerView显示 4cards编号为1 4 这些卡片占据了屏幕的整个宽度 因此一次只能完全看到一张卡片 用户会看到第一张卡 当他们像这样向左滑动卡时 the RecyclerView将一直滚动到数字 4 我不想那样
  • 无法在 C++ 应用程序中导入 dll

    我有一个名为hecom32 dll 我想在我的应用程序中使用它 我确认以下内容 import hecom32 dll 我收到以下错误 enter Error 1 error C1083 Cannot open type library fi
  • 对于动态、个性化的 Web 应用程序来说,多长的响应时间才被认为是良好的响应时间? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • randomBytes 与伪RandomBytes

    在什么情况下 从安全角度来看 使用节点的crypto pseudoRandomBytes http nodejs org api crypto html crypto crypto pseudorandombytes size callba
  • 如何防止 Xcode 7 Playgrounds 自动运行?

    我正在开发一个 Xcode 7 Playground 它可以同时运行很多东西 每当我进行编辑时 它都会刷新 重新启动正在运行的内容并再次运行整个代码 大约每 15 分钟就会让我的游乐场崩溃 有没有办法阻止游乐场在我进行编辑时自动运行 在游乐
  • 使用seaborn绘制系列

    category df category name column value counts 我有上面的系列返回值 CategoryA 100 CategoryB 200 我试图在 X 轴上绘制前 5 个类别名称 在 y 轴上绘制值 head
  • 在 AngularJS 中递归访问父指令的控制器

    我需要获取父级的控制器 因此我的指令有一个 require 属性 如下所示 module directive tag function return require tag restrict E controller function th
  • MySQL Grant 用于多个数据库

    我试图同时设置两个数据库的权限 我知道可以在两个语句中分配它们 有没有办法一劳永逸地做到这一点 I tried GRANT ALL PRIVILEGES ON mydb1 mydb2 TO reader localhost IDENTIFI
  • open_uri / Nokogiri 重定向问题

    我正在使用 Nokogiri 来抓取一个可以正常工作的网页 除非该页面有重定向循环 所以当我抓取这个网站时 https www cardcomplete com besuchen isie uns auf facebook https ww
  • MonoTouch 和 Xcode 4

    既然 Xcode 4 GM 种子已经发布 MonoDevelop 最终会以某种方式与其交互以进行 XIB 编辑吗 我目前正在将每个 XIB 上的 打开方式 手动设置为旧的 Interface Builder 但是这样做有两个问题 我必须记住
  • 这个 JavaScript/jQuery 语法是什么意思?

    下面的语法是什么意思 function fn columnize function options What s function What s fn 在编写插件时使用此约定 以确保使用 符号与其他 Javascript 库不发生冲突 同时
  • 如何获取表格单元格中的标签以继续到下一行而不是被切断屏幕? (Xcode 8)

    所以基本上我将文本从数组加载到表视图中的单元格中 但不是像我想要的那样继续到下一行 而是输入的文本标签在单个单元格中从屏幕上被截断 我在网上查了一下 据说将 numberOfLines 设置为 0 将 lineBreakMode 设置为 N
  • 用 protected 覆盖受保护的内部!

    这是一extension为了这question https stackoverflow com questions 2375556 overriding and overridden methods must have same acces
  • Autotools:如何清理lighttpd项目中“./configure”创建的文件?

    我正在尝试lighttpd用于嵌入式 Linux 项目 我获得了最新的源代码包 并开始编写一个主 Makefile 其中封装了所有配置 编译 安装 用于测试 等内容 反之亦然 我想清理每一步 清理后应该不再有生成的文件 这对于重复测试很重要
  • 调查 apache 基准测试失败的请求

    我今天才开始用AB 阅读了几个关于新的 AB 教程 并想尝试一下对我的网站进行负载测试 使用它几次后 我收到了大量失败的请求 您能解释一下失败的请求是什么意思吗 我怎样才能进一步调查这个问题 AB 结果示例 jailshell 3 2 ab
  • 通过 es.map() 和 JSONStream.stringify() 将 JSONStream.parsed() 数据传输到文件流时,节点堆耗尽

    我正在尝试通过 JSONStream parse 通过管道传输输入流 从巨大的 GeoJSON 文件创建 以将流分解为对象 然后通过 event stream map 以允许我转换对象 然后通过 JSONStream stringify 创