我試圖通過JSONStream.parse管道輸入流(從巨大的GeoJSON文件創建) ()將流分解成對象,然後通過event-stream.map()讓我轉換對象,然後通過JSONStream.stringify()創建一個字符串,最後創建一個可寫的輸出流。隨着進程的運行,我可以看到節點的內存佔用量繼續增長,直到最終耗盡堆。下面是重現該問題的最簡單的腳本(test.js):即噴出JSON源源不斷地爲節點的process.stdin會造成節點的堆逐步成長當通過es.map()和JSONStream.stringify()管道JSONStream.parsed()將文件流管道輸入流
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):
#!/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(出)」 改變最後一個管道階段 「.pipe(process.stdout)」,然後管節點的標準輸出到/ dev/null的
- 更改異步es.map()同步es.mapSync()
前兩個動作之一將允許腳本永遠運行,節點的內存佔用低且不變。我在運行Ubuntu 16.04的8GB內存的八核心機器上使用節點v6.3.1,事件流v3.3.4和JSONStream 1.1.4。
我希望有人能幫助我糾正我所確定的一個明顯的錯誤。
謝謝。我直言不諱地說,爲什麼將目標流更改爲process.stdout允許代碼無限期地運行而不增加內存。你能重現那種行爲嗎? – nw31304
對我來說,它似乎仍然管道傳輸到'stdout'時消耗的內存,但在* *得多率較低。我猜'fs'基礎結構必須比'stdout'慢 - 即使是'/ dev/null'。這是所有推送流的問題;您可以使用RxJS進入類似的情況。我認爲你最好的選擇是做一些試驗來暫停閱讀。也許每隔1000個功能就會暫停一下? – cartant