server.js 内存泄漏 |反应/快递/SSR
Memory Leak in server.js | React / Express / SSR
我是 运行 一个在 nodejs 服务器上呈现的 React 应用程序。几天后看到nodeJs进程的内存随着访问量的增加而增加。每次我重新加载页面时,内存使用量都会增加一点。
一开始,该过程大约需要 ~60MB 内存。几天后,它增加到 ~450MB。现在我正在重新启动节点进程来解决这个问题。
我认为这是我的 React 设置的问题。即使我只渲染一个非常小的应用程序,我也会泄漏。示例:
// Express server
app.get('*', async (req, res, next) => {
try {
const html = ReactDOM.renderToStaticMarkup(
<html>
<head />
<body>
<h1>hello</h1>
</body>
</html>,
);
res.status(200);
res.send(`<!doctype html>${html}`);
} catch (err) {
next(err);
}
});
为了检查内存泄漏,我每 3 秒强制进行一次垃圾收集,并在使用 autocannon 发出几千个请求时打印出内存使用情况。这给出了以下结果:
Program is using 16234160 bytes of Heap. // Start, no requests yet
Program is using 16177744 bytes of Heap.
Program is using 16177864 bytes of Heap.
Program is using 15185808 bytes of Heap. // Idle heap
Program is using 15185808 bytes of Heap.
Program is using 15185808 bytes of Heap.
Program is using 15185808 bytes of Heap.
Program is using 19199696 bytes of Heap. // Beginning of first 10k requests
Program is using 20890376 bytes of Heap.
Program is using 20201600 bytes of Heap. // New idle heap
Program is using 20201600 bytes of Heap.
Program is using 20201600 bytes of Heap.
Program is using 20201600 bytes of Heap.
Program is using 21761368 bytes of Heap. // Beginning of second 10k requests
Program is using 23862168 bytes of Heap.
Program is using 25191168 bytes of Heap.
Program is using 24731176 bytes of Heap.
Program is using 24512424 bytes of Heap. // New idle heap
Program is using 24512424 bytes of Heap.
Program is using 24512424 bytes of Heap.
当我渲染 "real" React 应用程序时,内存使用量当然会增加很多。以下屏幕截图显示了第一次启动应用程序和 对页面的单个请求 之间的区别:
如果我只 return 一个没有 React 的 renderToStaticMarkup
的字符串,问题就消失了(例如 res.send("<!doctype html><html><head /><body><h1>hello</h1></body></html>");
.
我是不是漏掉了什么?或者是否存在已知问题?还是快递问题?
我 运行 在节点 v8.4.0
上,这是我的依赖项(我正在使用 react-starter-kit):
"dependencies": {
"@babel/polyfill": "^7.0.0-beta.44",
"bluebird": "^3.5.1",
"body-parser": "^1.18.2",
"classnames": "^2.2.5",
"cookie-parser": "^1.4.3",
"core-js": "^2.5.4",
"express": "^4.17.1",
"express-http-proxy": "^1.1.0",
"express-jwt": "^5.3.1",
"history": "^4.7.2",
"intl": "^1.2.5",
"isomorphic-fetch": "^2.2.1",
"isomorphic-style-loader": "^4.0.0",
"node-fetch": "^2.1.2",
"normalize.css": "^8.0.0",
"pretty-error": "^2.1.1",
"prop-types": "^15.6.1",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-helmet": "^5.2.0",
"react-slick": "0.23.1",
"serialize-javascript": "^1.4.0",
"smoothscroll-polyfill": "^0.4.4",
"source-map-support": "^0.5.4",
"universal-router": "^6.0.0",
"whatwg-fetch": "^2.0.4"
},
我做了更多测试,发现当我在 development
(调试)模式下构建应用程序时,泄漏消失了。
经过一些调查,我发现这个 babel 插件只在 production
模式下加载到我的 webpack 文件中:https://babeljs.io/docs/en/babel-plugin-transform-react-constant-elements
我删除那个插件后,内存泄漏就消失了。我想这个插件应该只为客户端应用程序加载,因为插件的作用是
"Treat React JSX elements as value types and hoist them to the highest scope"
当您关闭 page/tab 时,范围在客户端应用程序上消失,这没什么大不了的,但在节点服务器上,它会导致内存随着每个请求而增加。
我是 运行 一个在 nodejs 服务器上呈现的 React 应用程序。几天后看到nodeJs进程的内存随着访问量的增加而增加。每次我重新加载页面时,内存使用量都会增加一点。 一开始,该过程大约需要 ~60MB 内存。几天后,它增加到 ~450MB。现在我正在重新启动节点进程来解决这个问题。
我认为这是我的 React 设置的问题。即使我只渲染一个非常小的应用程序,我也会泄漏。示例:
// Express server
app.get('*', async (req, res, next) => {
try {
const html = ReactDOM.renderToStaticMarkup(
<html>
<head />
<body>
<h1>hello</h1>
</body>
</html>,
);
res.status(200);
res.send(`<!doctype html>${html}`);
} catch (err) {
next(err);
}
});
为了检查内存泄漏,我每 3 秒强制进行一次垃圾收集,并在使用 autocannon 发出几千个请求时打印出内存使用情况。这给出了以下结果:
Program is using 16234160 bytes of Heap. // Start, no requests yet
Program is using 16177744 bytes of Heap.
Program is using 16177864 bytes of Heap.
Program is using 15185808 bytes of Heap. // Idle heap
Program is using 15185808 bytes of Heap.
Program is using 15185808 bytes of Heap.
Program is using 15185808 bytes of Heap.
Program is using 19199696 bytes of Heap. // Beginning of first 10k requests
Program is using 20890376 bytes of Heap.
Program is using 20201600 bytes of Heap. // New idle heap
Program is using 20201600 bytes of Heap.
Program is using 20201600 bytes of Heap.
Program is using 20201600 bytes of Heap.
Program is using 21761368 bytes of Heap. // Beginning of second 10k requests
Program is using 23862168 bytes of Heap.
Program is using 25191168 bytes of Heap.
Program is using 24731176 bytes of Heap.
Program is using 24512424 bytes of Heap. // New idle heap
Program is using 24512424 bytes of Heap.
Program is using 24512424 bytes of Heap.
当我渲染 "real" React 应用程序时,内存使用量当然会增加很多。以下屏幕截图显示了第一次启动应用程序和 对页面的单个请求 之间的区别:
如果我只 return 一个没有 React 的 renderToStaticMarkup
的字符串,问题就消失了(例如 res.send("<!doctype html><html><head /><body><h1>hello</h1></body></html>");
.
我是不是漏掉了什么?或者是否存在已知问题?还是快递问题?
我 运行 在节点 v8.4.0
上,这是我的依赖项(我正在使用 react-starter-kit):
"dependencies": {
"@babel/polyfill": "^7.0.0-beta.44",
"bluebird": "^3.5.1",
"body-parser": "^1.18.2",
"classnames": "^2.2.5",
"cookie-parser": "^1.4.3",
"core-js": "^2.5.4",
"express": "^4.17.1",
"express-http-proxy": "^1.1.0",
"express-jwt": "^5.3.1",
"history": "^4.7.2",
"intl": "^1.2.5",
"isomorphic-fetch": "^2.2.1",
"isomorphic-style-loader": "^4.0.0",
"node-fetch": "^2.1.2",
"normalize.css": "^8.0.0",
"pretty-error": "^2.1.1",
"prop-types": "^15.6.1",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-helmet": "^5.2.0",
"react-slick": "0.23.1",
"serialize-javascript": "^1.4.0",
"smoothscroll-polyfill": "^0.4.4",
"source-map-support": "^0.5.4",
"universal-router": "^6.0.0",
"whatwg-fetch": "^2.0.4"
},
我做了更多测试,发现当我在 development
(调试)模式下构建应用程序时,泄漏消失了。
经过一些调查,我发现这个 babel 插件只在 production
模式下加载到我的 webpack 文件中:https://babeljs.io/docs/en/babel-plugin-transform-react-constant-elements
我删除那个插件后,内存泄漏就消失了。我想这个插件应该只为客户端应用程序加载,因为插件的作用是
"Treat React JSX elements as value types and hoist them to the highest scope"
当您关闭 page/tab 时,范围在客户端应用程序上消失,这没什么大不了的,但在节点服务器上,它会导致内存随着每个请求而增加。