server.js中的内存泄漏|反应/快速/ SSR

时间:2019-08-21 20:51:31

标签: node.js reactjs express memory-leaks garbage-collection

我正在运行一个在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.

当我渲染“真实的” React应用程序时,内存使用量当然会大大增加。以下屏幕快照显示了首次启动该应用程序和对该页面的一个单一请求之间的区别:

comparison

如果我只返回没有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"
  },

1 个答案:

答案 0 :(得分:0)

我进行了更多测试,发现在development(调试)模式下构建应用程序时,泄漏已消失。 经过一番调查,我发现此babel插件仅以production模式加载到我的webpack文件中:https://babeljs.io/docs/en/babel-plugin-transform-react-constant-elements

删除该插件后,内存泄漏消失了。我猜应该只为客户端应用加载此插件,因为该插件的作用是

“将React JSX元素作为值类型进行处理,并将其提升到最高范围”

由于在关闭页面/选项卡时客户端应用程序的作用域已不那么重要,但是在节点服务器上,它将导致内存随每个请求而建立。