You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何降低createReadStream管道传输到响应时的高内存占用?

问题原因

你观测到的内存上涨是Linux操作系统的页缓存占用,并非Node.js应用自身的内存消耗:

  • Linux内核默认会将读取过的文件内容暂存在页缓存中,只要系统空闲内存充足就会保留,用于降低后续重复读取相同文件的磁盘IO开销。这部分内存属于可回收资源,当应用实际需要申请内存时,内核会自动释放页缓存空间,不会导致内存不足问题。
  • 你看到的容器总内存统计包含了这部分页缓存,如果你单独查看Node.js进程的RSS(常驻内存),会发现数值稳定在几十MB级别,不会随读取的文件大小线性上涨,这才是流实际带来的内存优化效果。

可选优化方案

如果你确实需要避免页缓存占用,可以通过以下两种方式调整:

1. 绕开系统页缓存直接读取文件

在创建读取流时传入O_DIRECT标志,跳过操作系统页缓存层直接从磁盘读取内容:

const express = require('express')
const fs = require('fs')
const app = express()
const port = 3000

// O_DIRECT对应的数值在Linux系统下为040000
app.get('/', (req, res) => {
    let stuff = fs.createReadStream('./large-file', {
        highWaterMark: 64 * 1024,
        flags: 0o40000 // 对应O_DIRECT标志,绕开系统页缓存
    });
    stuff.pipe(res);
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

注意:O_DIRECT存在平台兼容性限制,且会降低文件读取性能,没有特殊需求不建议开启。

2. 缩小流的内部缓冲区大小

可以通过调整highWaterMark参数,控制Node.js流内部的缓冲区上限,进一步降低应用层面的内存占用,默认值为64KB,示例:

let stuff = fs.createReadStream('./large-file', { highWaterMark: 16 * 1024 })

验证方法

你可以通过以下命令确认Node.js进程的实际内存占用,避免和系统缓存混淆:

# 查看node进程的RSS内存,单位为KB
ps -o rss= $(pgrep node)

内容的提问来源于stack exchange,提问作者yolob 21

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 03:15:10