V8 Getheapshot使玩笑无限地悬挂

发布于 2025-02-13 18:37:40 字数 1118 浏览 0 评论 0原文

目前,我的代码中有一个内存泄漏,我正在尝试通过使用节点V8库创建堆快照来调试它。我正在使用Express创建一个可以调用的TypeScript中的端点,它应该返回可以写入文件并导入Chrome Dev工具的JSON对象。

但是,当我运行Jest测试以测试无限期悬挂的端点时。 我目前正在调用

jest --runInBand InfoController.test.ts

infocontroller.ts

import { Router } from 'express';
import { getHeapSnapshot } from 'v8';
import { constants } from 'http2';

export const InfoController = (): Router => {
  const router = Router();
  router.get('/heapdump', (_, res) => {
    console.log('requesting heap snapshot')
    const heapShot = getHeapSnapshot();
    console.log('heap');
    let data = '';
    heapShot.on('readable', () => {
      const chunk = heapShot.read();
      while (chunk !== null) {
        data += chunk;
      }
    });

    heapShot.on('end', () => res.status(constants.HTTP_STATUS_OK).json(JSON.parse(data)));
  });

  return router;
};

infocontroller.test.ts

import express from 'express';
import { constants as httpConstants } from 'http2';
import Request from 'supertest';
import { InfoController } from './InfoController';

describe('
              

Currently, I have a memory leak in my code and I'm trying to debug it by creating a heap snapshot using Nodes v8 library. I'm creating an endpoint in typescript using express which I can call and it should return a JSON object that can be written to a file and imported into chrome dev tools.

However, when I run my jest test to test the endpoint it hangs indefinitely.
I'm currently calling

jest --runInBand InfoController.test.ts

InfoController.ts

import { Router } from 'express';
import { getHeapSnapshot } from 'v8';
import { constants } from 'http2';

export const InfoController = (): Router => {
  const router = Router();
  router.get('/heapdump', (_, res) => {
    console.log('requesting heap snapshot')
    const heapShot = getHeapSnapshot();
    console.log('heap');
    let data = '';
    heapShot.on('readable', () => {
      const chunk = heapShot.read();
      while (chunk !== null) {
        data += chunk;
      }
    });

    heapShot.on('end', () => res.status(constants.HTTP_STATUS_OK).json(JSON.parse(data)));
  });

  return router;
};

InfoController.test.ts

import express from 'express';
import { constants as httpConstants } from 'http2';
import Request from 'supertest';
import { InfoController } from './InfoController';

describe('???? InfoController', () => {
  describe('GET /heapdump', () => {
    test('should be able to retrieve a v8 heapdump of the service', async () => {
      const controller = InfoController();

      const app = express();
      app.use(express.json());
      app.use(controller);

      const result = await Request(app).get('/heapdump').expect(httpConstants.HTTP_STATUS_OK);
      console.log(result.body);
    });
  });
});

jest.config.js

module.exports = {
  preset: 'ts-jest',
  bail: true,
  verbose: true,
  testEnvironment: 'node',
  collectCoverage: false,
  testMatch: ['**/**/*.test.ts'],
  testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/build/'],
  collectCoverageFrom: ['<rootDir>/src/**', '!<rootDir>/src/index.ts'],
  coveragePathIgnorePatterns: ['<rootDir>/node_modules', '<rootDir>/__tests__'],
  globalSetup: '<rootDir>/__tests__/global/setup.ts',
};

This is the output I'm getting

$ jest --runInBand src/http/controllers/InfoController.test.ts
console.log
    requesting heap snapshot

      at src/http/controllers/InfoController.ts:8:13


 RUNS  src/http/controllers/InfoController.test.ts

After this, it just hangs and never completes ????

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奶茶白久 2025-02-20 18:37:40

在您的代码中心考虑此片段:

      const chunk = heapShot.read();
      while (chunk !== null) {
        data += chunk;
      }

如果始终是无效的(这几乎可以保证发生),这将永远循环(或者,至少,直到Data Data变得如此之大,以至于整个过程将随着OOM而崩溃)。

官方文档显示了一种可能性修改snippet的可能性:

  let chunk;
  while ((chunk = heapShot.read()) !== null) {
    data += chunk;
  }

Consider this snippet at the center of your code:

      const chunk = heapShot.read();
      while (chunk !== null) {
        data += chunk;
      }

If chunk is ever non-null (which is pretty much guaranteed to happen), that will loop forever (or, well, at least until data becomes so big that the whole process will crash with OOM).

The official documentation shows one possibility how to modify the snippet to make it work:

  let chunk;
  while ((chunk = heapShot.read()) !== null) {
    data += chunk;
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文