我的 Jests 测试正在泄漏内存,我该如何解决这个问题?

hel*_*ont 27 memory node.js reactjs jestjs

当我运行笑话测试时,每个测试使用的内存量随着时间的推移而增加。这个问题在我的本地机器上并不明显;相反,我在 CircleCI 上运行测试时发现了这一点。我收到以下错误:

\n
 FAIL  __tests__/pages/login.test.tsx\n \n  \xe2\x97\x8f Test suite failed to run\n \n    jest: failed to cache transform results in: /tmp/jest_2ne/jest-transform-cache-7bdebd1a0c578519274d14a78b89f87c-f8238a99880aac6151736010e575fab1/0b/symbols_0bf4cffb45cb261625f2f3fca21a4789.map\n \n    Failure message: ENOMEM: not enough memory, write\n \n      at writeFileSync (node_modules/write-file-atomic/index.js:215:10)\n      at writeCacheFile (node_modules/@jest/transform/build/ScriptTransformer.js:809:33)\n      at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:554:7)\n      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:586:40)\n      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:624:25)\n
Run Code Online (Sandbox Code Playgroud)\n

如何修复 jest 配置以防止出现这种情况?

\n

hel*_*ont 33

首先,通过使用以下选项运行 jest 来确保您进行了泄漏测试: jest --logHeapUsage

运行测试并检查内存消耗是否随着时间的推移而增加,如下所示(文件名已更改):

PASS  __tests__/pages/file.test.tsx (181 MB heap size)
 PASS  __tests__/pages/file2.test.tsx (193 MB heap size)
 PASS  __tests__/components/Header/file3.test.tsx (201 MB heap size)
 PASS  __tests__/components/Header/file4.test.tsx (192 MB heap size)
 PASS  __tests__/components/Header/file5.test.tsx (218 MB heap size)
 PASS  __tests__/pages/file6.test.tsx (201 MB heap size)
 PASS  __tests__/components/file6.test.tsx (203 MB heap size)
 PASS  __tests__/components/file7.test.tsx (213 MB heap size)
 PASS  __tests__/components/file8.test.tsx (234 MB heap size)
 PASS  __tests__/components/file9.test.tsx (222 MB heap size)
 PASS  __tests__/components/file10.test.tsx (240 MB heap size)
 PASS  __tests__/components/file11.test.tsx (231 MB heap size)
 PASS  __tests__/utils/file12.test.tsx (239 MB heap size)
 PASS  __tests__/components/file13.test.tsx (251 MB heap size)
 PASS  __tests__/components/file14.test.tsx (239 MB heap size)
 PASS  __tests__/components/file15.test.tsx (249 MB heap size)
 PASS  __tests__/components/file16.test.tsx (143 MB heap size)
Run Code Online (Sandbox Code Playgroud)

要解决此问题,请将您的npm run testyarn test命令更改package.json为: node --expose-gc ./node_modules/.bin/jest --runInBand --logHeapUsage

运行命令。这是我的输出:

 PASS  __tests__/components/file.test.tsx (143 MB heap size)
 PASS  __tests__/pages/onboarding/file1.test.tsx (149 MB heap size)
 PASS  __tests__/components/file2.test.tsx (146 MB heap size)
 PASS  __tests__/components/file3.test.tsx (146 MB heap size)
 PASS  __tests__/components/file4.test.tsx (153 MB heap size)
 PASS  __tests__/components/Header /file5.test.tsx (149 MB heap size)
 PASS  __tests__/pages/file6.test.tsx (149 MB heap size)
 PASS  __tests__/pages/file7.test.tsx (149 MB heap size)
 PASS  __tests__/components/file8.test.tsx (147 MB heap size)
 PASS  __tests__/components/file9.test.tsx (148 MB heap size)
 PASS  __tests__/pages/file10.test.tsx (148 MB heap size)
 PASS  __tests__/components/Header /file11.test.tsx (148 MB heap size)
 PASS  __tests__/functions/file12.test.tsx (149 MB heap size)
 PASS  __tests__/components/file13.test.tsx (148 MB heap size)
 PASS  __tests__/components/file14.test.tsx (150 MB heap size)
 PASS  __tests__/components/file15.test.tsx (150 MB heap size)
 PASS  __tests__/components/Header /file16.test.tsx (149 MB heap size)
 PASS  __tests__/components/file17.test.tsx (149 MB heap size)
 PASS  __tests__/utils/file18.test.tsx (150 MB heap size)
 PASS  __tests__/components/file19.test.tsx (149 MB heap size)
 PASS  __tests__/pages/file20.test.tsx (150 MB heap size)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,内存消耗更加一致。

您可以在此 Github 问题中阅读有关此问题和解决方案的更多信息,该问题描述了 jest 的垃圾收集器泄漏问题。


xab*_*xab 18

我在运行集成测试时遇到了同样的问题,最初堆大小约为 160MB,本地爬升至约 1600MB,并在 CI 中出现 OOM。此问题还导致随机测试开始失败,Exceeded timeout of 5000 ms for a test.
可以在此处找到此问题的主要讨论,在顶部您可以找到该问题的快速修复方法。要修复此问题,您必须workerIdleMemoryLimit在配置中设置该标志:

// jest.config.js

/** @type {import('jest').Config} */
const config = {
    workerIdleMemoryLimit: '512MB',
};

module.exports = config;
Run Code Online (Sandbox Code Playgroud)

环境:

  • 节点:16.15.0
  • 笑话:29.5.0
  • ts-笑话:29.0.5

更改配置后,堆大小保持在限制以下并修复了超时失败问题。
作为额外的好处,测试在本地运行速度更快约 20 秒,在 CI 中运行速度约 4 分钟(使用--maxWorkers 4cli 选项)


小智 12

您可以使用它jest -w 1来避免这些内存问题。

有关Jest CLI 文档的更多信息

--maxWorkers=|# 别名:-w. 指定工作池为运行测试而生成的最大工作人员数量。在单运行模式下,这默认为计算机上可用的核心数减去主线程的一数。在监视模式下,这默认为机器上可用内核的一半,以确保 Jest 不引人注目并且不会让您的机器停止运行。在 CI 等资源有限的环境中调整此设置可能很有用,但默认值应该足以满足大多数用例。


vin*_*oxx 7

我的环境是:

  • 节点18.12.1
  • 开玩笑 29.3.1
  • ts-jest 29.0.3

我运行测试的 npm 脚本是jest --coverage. 当我运行测试时出现此错误

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
Run Code Online (Sandbox Code Playgroud)

v8作为承保提供商对我来说很有效。

// Example jest.config.js
module.exports = {
    coverageProvider: 'v8', // Default is 'babel'
    transform: {
        '\\.[jt]sx?$': 'ts-jest'
    }
};
Run Code Online (Sandbox Code Playgroud)

参考号 https://jestjs.io/docs/configuration#coverageprovider-string

  • 注意:内存泄漏和内存不足是两件不同的事情。您的环境内存不足。 (2认同)