Angular 13在Azure DevOps构建频繁内存不足,max_old_space_size无效
Angular 13 Azure DevOps构建内存不足问题排查与解决
问题背景
项目升级到Angular 13后,在Azure DevOps执行构建时,约每3次就会因内存问题失败,报错内容各异但均指向内存不足。已尝试设置max_old_space_size,但问题仍未解决,需寻找更有效的内存优化方案。
常见错误类型
类型1:DataCloneError内存不足
##[error]Error(0,0): Error [main.5aa4446f2024043f.js: ;]DataCloneError: Data cannot be cloned, out of memory. Error : Optimization error [main.5aa4446f2024043f.js]: DataCloneError: Data cannot be cloned, out of memory. [D:\a\1\s\MyApp\MyApp.Web\MyApp.Web.csproj] at WorkerInfo.postTask (D:\a\1\s\MyApp\MyApp.Web\ClientApp\node_modules\piscina\dist\src\index.js:305:23) at ThreadPool._onWorkerAvailable (D:\a\1\s\MyApp\MyApp.Web\ClientApp\node_modules\piscina\dist\src\index.js:518:24) at D:\a\1\s\MyApp\MyApp.Web\ClientApp\node_modules\piscina\dist\src\index.js:381:46 at AsynchronouslyCreatedResourcePool.maybeAvailable (D:\a\1\s\MyApp\MyApp.Web\ClientApp\node_modules\piscina\dist\src\index.js:237:17) at WorkerInfo.onMessage (D:\a\1\s\MyApp\MyApp.Web\ClientApp\node_modules\piscina\dist\src\index.js:424:26) at WorkerInfo._handleResponse (D:\a\1\s\MyApp\MyApp.Web\ClientApp\node_modules\piscina\dist\src\index.js:289:14) at MessagePort.<anonymous> (D:\a\1\s\MyApp\MyApp.Web\ClientApp\node_modules\piscina\dist\src\index.js:258:51) at MessagePort.[nodejs.internal.kHybridDispatch] (node:internal/event_target:643:20) at MessagePort.exports.emitMessage (node:internal/per_context/messageport:23:28)
类型2:V8 Zone内存耗尽致命错误
#FailureMessage Object: 0000001D9D3F9EB0 # # Fatal error in , line 0 # Fatal process out of memory: Zone # # # #FailureMessage Object: 0000001D9D2FA470 1: 00007FF783AF79CF public: __cdecl v8::internal::CodeObjectRegistry::~CodeObjectRegistry(void) __ptr64+114207 2: 00007FF783A13E9F public: class std::basic_ostream<char,struct std::char_traits<char> > & __ptr64 __cdecl std::basic_ostream<char,struct std::char_traits<char> >::operator<<(__int64) __ptr64+65103 3: 00007FF7846F26C2 void __cdecl V8_Fatal(char const * __ptr64,...)+162 4: 00007FF7843A55DE public: void __cdecl v8::SharedArrayBuffer::Externalize(class std::shared_ptr<class v8::BackingStore> const & __ptr64) __ptr64+286 5: 00007FF783F3FA57 private: unsigned __int64 __cdecl v8::internal::Zone::NewExpand(unsigned __int64) __ptr64+279 6: 00007FF783D4EAE4 public: virtual char const * __ptr64 __cdecl disasm::NameConverter::NameOfXMMRegister(int)const __ptr64+17108 7: 00007FF7847752F0 public: void __cdecl v8::internal::compiler::Schedule::AddGoto(class v8::internal::compiler::BasicBlock * __ptr64,class v8::internal::compiler::BasicBlock * __ptr64) __ptr64+48 8: 00007FF7848E47D2 private: void __cdecl v8::internal::compiler::Scheduler::ComputeSpecialRPONumbering(void) __ptr64+3490 9: 00007FF7848E3B88 private: void __cdecl v8::internal::compiler::Scheduler::ComputeSpecialRPONumbering(void) __ptr64+344 10: 00007FF7848E752D private: static void __cdecl v8::internal::compiler::Scheduler::PropagateImmediateDominators(class v8::internal::compiler::BasicBlock * __ptr64)+3101 11: 00007FF7848E29A5 private: void __cdecl v8::internal::compiler::Scheduler::BuildCFG(void) __ptr64+277 12: 00007FF7848E380E public: static class v8::internal::compiler::Schedule * __ptr64 __cdecl v8::internal::compiler::Scheduler::ComputeSchedule(class v8::internal::Zone * __ptr64,class v8::internal::compiler::Graph * __ptr64,class v8::base::Flags<enum v8::internal::compiler::Scheduler::Flag,int>,class v8::internal::TickCounter * __ptr64,class v8::internal::ProfileDataFromFile const * __ptr64)+270 13: 00007FF7847A2CA9 public: bool __cdecl v8::internal::compiler::LoopPeeler::CanPeel(class v8::internal::compiler::LoopTree::Loop * __ptr64) __ptr64+185 14: 00007FF7847A83FB public: class v8::internal::compiler::LifetimePosition __cdecl v8::internal::compiler::LiveRange::NextStart(void)const __ptr64+2043 15: 00007FF7847A3BC1 public: class v8::internal::compiler::LifetimePosition __cdecl v8::internal::compiler::LiveRange::End(void)const __ptr64+177 16: 00007FF78433CFF1 public: enum v8::internal::CompilationJob::Status __cdecl v8::internal::OptimizedCompilationJob::ExecuteJob(class v8::internal::RuntimeCallStats * __ptr64,class v8::internal::LocalIsolate * __ptr64) __ptr64+49 17: 00007FF78430DF49 private: void __cdecl v8::internal::OptimizingCompileDispatcher::CompileNext(class v8::internal::OptimizedCompilationJob * __ptr64,class v8::internal::LocalIsolate * __ptr64) __ptr64+57 18: 00007FF78430EA1A public: void __cdecl v8::internal::OptimizingCompileDispatcher::QueueForOptimization(class v8::internal::OptimizedCompilationJob * __ptr64) __ptr64+714 19: 00007FF783A1682D public: class std::basic_ostream<char,struct std::char_traits<char> > & __ptr64 __cdecl std::basic_ostream<char,struct std::char_traits<char> >::operator<<(__int64) __ptr64+75741 20: 00007FF783B46EDD uv_poll_stop+557 21: 00007FF784960120 public: class v8::internal::compiler::Operator const * __ptr64 __cdecl v8::internal::compiler::RepresentationChanger::Uint32OverflowOperatorFor(enum v8::internal::compiler::IrOpcode::Value) __ptr64+146416 22: 00007FF80C834ED0 BaseThreadInitThunk+16 23: 00007FF80D26E39B RtlUserThreadStart+43
类型3:JavaScript堆内存不足
<--- Last few GCs ---> [6640:000001CC0BCB3FC0] 21334 ms: Scavenge 87.4 (107.8) -> 78.6 (111.3) MB, 9.5 / 0.0 ms (average mu = 0.992, current mu = 0.990) allocation failure [6640:000001CC0BCB3FC0] 21397 ms: Scavenge 91.4 (111.8) -> 82.6 (115.5) MB, 21.7 / 0.0 ms (average mu = 0.992, current mu = 0.990) allocation failure [6640:000001CC0BCB3FC0] 21783 ms: Scavenge 95.6 (116.0) -> 86.7 (119.5) MB, 158.3 / 0.0 ms (average mu = 0.992, current mu = 0.990) allocation failure <--- JS stacktrace ---> <--- Last few GCs ---> [6640:000001CC0BCB3FC0] 21334 ms: Scavenge 87.4 (107.8) -> 78.6 (111.3) MB, 9.5 / 0.0 ms (average mu = 0.992, current mu = 0.990) allocation failure [6640:000001CC0BCB3FC0] 21397 ms: Scavenge 91.4 (111.8) -> 82.6 (115.5) MB, 21.7 / 0.0 ms (average mu = 0.992, current mu = 0.990) allocation failure [6640:000001CC0BCB3FC0] 21783 ms: Scavenge 95.6 (116.0) -> 86.7 (119.5) MB, 158.3 / 0.0 ms (average mu = 0.992, current mu = 0.990) allocation failure <--- JS stacktrace ---> <--- Last few GCs ---> [6640:000001CC0BD4A7B0] 21478 ms: Scavenge 56.2 (76.6) -> 47.2 (80.1) MB, 17.0 / 0.0 ms (average mu = 0.996, current mu = 0.996) allocation failure [6640:000001CC0BD4A7B0] 22725 ms: Scavenge 60.5 (80.8) -> 51.3 (82.6) MB, 1020.4 / 0.0 ms (average mu = 0.996, current mu = 0.996) allocation failure [6640:000001CC0BD4A7B0] 27389 ms: Scavenge 62.7 (83.1) -> 54.9 (85.6) MB, 1839.8 / 0.0 ms (average mu = 0.996, current mu = 0.996) allocation failure <--- JS stacktrace ---> ##[error]EXEC(0,0): Error : MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory EXEC : FATAL error : MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory [D:\a\1\s\BehaviorLive\BehaviorLive.Web\BehaviorLive.Web.csproj] ##[error]EXEC(0,0): Error : MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory EXEC : FATAL error : MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory [D:\a\1\s\BehaviorLive\BehaviorLive.Web\BehaviorLive.Web.csproj] ##[error]EXEC(0,0): Error : MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory
优化方案
1. 正确设置Node.js内存参数
避免通过环境变量间接设置,直接在构建命令前指定内存参数,确保构建进程能直接读取:
node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng build --configuration production
根据项目大小可调整内存值(如12288对应12GB)。
2. 禁用并行构建与优化
Angular 13默认并行处理构建任务,会大幅增加内存占用。修改angular.json:
{ "projects": { "your-project-name": { "architect": { "build": { "options": { "parallel": false, "maxWorkers": 1 }, "configurations": { "production": { "optimization": { "scripts": { "parallel": false } } } } } } } } }
3. 拆分大型构建任务
将项目拆分为公共库和主应用两个独立构建任务,先构建公共库,再构建主应用,减少单次构建的内存负载。
4. 升级Node.js版本
Angular 13推荐使用Node.js 14.x或16.x,新版本V8引擎优化了内存管理,能有效降低内存泄漏和占用过高的概率。
5. 清理冗余代码与依赖
- 用
npm ls排查未使用的第三方依赖,直接卸载; - 启用Angular的
strict模式和unusedImports规则,清理未使用的组件、模块和导入; - 压缩静态资源(图片、字体),减少构建时需处理的文件体积。
6. 调整Azure DevOps代理配置
- 使用Azure托管代理时,选择
windows-2022大内存实例; - 自托管代理需确保服务器至少有8GB以上可用内存,关闭其他占用内存的后台进程。
7. 生产环境禁用源映射
源映射会生成大量临时文件,占用额外内存,生产构建时关闭:
{ "configurations": { "production": { "sourceMap": false } } }
内容的提问来源于stack exchange,提问作者Chris Kooken
相关产品推荐
相关产品推荐

