프로젝트 시나리오:
최근에 저는 프론트엔드 React 프로젝트를 작성하고 있는데 이 프로젝트는 대규모 시스템을 위한 마이크로 프론트엔드 솔루션인 Ali Feibing의 icestark 마이크로 프론트엔드 솔루션을 사용합니다. 마이크로 모듈. 컴파일 후 기본 애플리케이션에 통합됩니다.
문제 설명
단일 마이크로 모듈이 상당히 크기 때문에 핫 업데이트 중에 임의로 변경하면 NodeJS의 V8 엔진의 메모리 스택 오버플로 문제를 자주 보고하게 됩니다.
<--- Last few GCs --->
[7210:0x7fe5fba00000] 325240 ms: Mark-sweep (reduce) 4036.4 (4117.0) -> 4036.1 (4108.8) MB, 1394.5 / 0.1 ms (average mu = 0.111, current mu = 0.063) allocation failure scavenge might not succeed
[7210:0x7fe5fba00000] 325244 ms: Scavenge (reduce) 4037.1 (4108.8) -> 4037.2 (4109.8) MB, 1.9 / 0.0 ms (average mu = 0.111, current mu = 0.063) allocation failure
<--- JS stacktrace --->
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 0x10d0282b5 node::Abort() [/usr/local/bin/node]
2: 0x10d028438 node::OnFatalError(char const*, char const*) [/usr/local/bin/node]
3: 0x10d19fbb7 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
4: 0x10d19fb53 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
5: 0x10d33e1d5 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/usr/local/bin/node]
6: 0x10d3421fb v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [/usr/local/bin/node]
7: 0x10d33eadc v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/usr/local/bin/node]
8: 0x10d33bf8a v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
9: 0x10d3492e0 v8::internal::Heap::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
10: 0x10d349361 v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
11: 0x10d3105dd v8::internal::FactoryBase<v8::internal::Factory>::NewRawOneByteString(int, v8::internal::AllocationType) [/usr/local/bin/node]
12: 0x10d710ec1 v8::internal::IncrementalStringBuilder::Extend() [/usr/local/bin/node]
13: 0x10d453244 v8::internal::JsonStringifier::SerializeString(v8::internal::Handle<v8::internal::String>) [/usr/local/bin/node]
14: 0x10d455058 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_<false>(v8::internal::Handle<v8::internal::Object>, bool, v8::internal::Handle<v8::internal::Object>) [/usr/local/bin/node]
15: 0x10d458ca4 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_<true>(v8::internal::Handle<v8::internal::Object>, bool, v8::internal::Handle<v8::internal::Object>) [/usr/local/bin/node]
16: 0x10d456307 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_<false>(v8::internal::Handle<v8::internal::Object>, bool, v8::internal::Handle<v8::internal::Object>) [/usr/local/bin/node]
17: 0x10d4502b3 v8::internal::JsonStringify(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>) [/usr/local/bin/node]
18: 0x10d226838 v8::internal::Builtin_JsonStringify(int, unsigned long*, v8::internal::Isolate*) [/usr/local/bin/node]
19: 0x10da64379 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit [/usr/local/bin/node]
20: 0x1128f63f0
21: 0x10da7728f Builtins_ArrayForEach [/usr/local/bin/node]
원인 분석:
힙 제한에 근접한 비효율적인 마크 압축 할당 실패 - JavaScript 힙 메모리 부족
자바스크립트 힙 메모리가 부족함 노드는 V8 엔진 기반 일반적인 백엔드 개발 언어에서는 기본 메모리 사용량에 제한이 없으나 노드에서 자바스크립트를 통해 메모리를 사용할 경우 메모리의 일부만 사용할 수 있음 (약 1.4GB, 32비트 시스템에서 약 0.7GB) 프론트 엔드 프로젝트가 매우 크면 웹팩이 많은 시스템 리소스를 차지하기 때문에 프로젝트를 컴파일할 때 메모리 누수가 발생하는 이유입니다. 컴파일할 때 노드의 기본 메모리 제한 크기가 이 오류를 보고합니다.
해결책:
사용된 마이크로 프런트엔드 아키텍처로 인해 빌드 도구는 Ali Feibing의 빌드 스크립트 모듈도 사용 하므로 인터넷에서 찾은 vue 프로젝트의 메모리 오버플로 구성도 유효하지 않습니다. 예를 들어 이것도 잘못되었습니다.
【빌드 스크립트 -max_old_space_size=8000 시작】
다음과 같이 변경해야만 유효합니다.
노드 --max_old_space_size=8000 node_modules/.bin/build-scripts 시작
node --max_old_space_size=8000 node_modules/.bin/build-scripts start
마지막으로 전체 package.json 파일을 첨부합니다.
{
"name": "@qc/qc-module",
"version": "1.0.0",
"description": "QC班长的微模块",
"files": [
"demo/",
"es/",
"lib/",
"build/"
],
"main": "lib/index.js",
"module": "es/index.js",
"stylePath": "style.js",
"scripts": {
"start": "node --max_old_space_size=8000 node_modules/.bin/build-scripts start",
"build": "build-scripts build",
"test": "build-scripts test",
"prepublishOnly": "npm run build",
"eslint": "eslint --cache --ext .js,.jsx,.ts,.tsx ./",
"eslint:fix": "npm run eslint -- --fix",
"stylelint": "stylelint \"**/*.{css,scss,less}\"",
"lint": "npm run eslint && npm run stylelint"
},
"keywords": [
"demo",
"react",
"component"
],
"dependencies": {
"@antv/g2plot": "^2.4.28",
"@ice/stark-module": "^1.5.0",
"@react-spring/web": "~9.5.5",
"ahooks": "^3.1.14",
"prop-types": "^15.5.8",
"react-to-print": "^2.14.12",
"umi-request": "^1.4.0"
},
"devDependencies": {
"@ant-design/icons": "^5.0.1",
"@iceworks/spec": "^1.0.0",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.2",
"build-plugin-component": "^1.0.0",
"build-plugin-stark-module": "^2.0.0",
"build-scripts": "^1.1.1",
"copy-webpack-plugin": "^5.1.2",
"enzyme": "^3.10.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"xlsx": "^0.18.5"
},
"peerDependencies": {
"react": "^16 || ^17"
},
"componentConfig": {
"name": "FormModuel",
"title": "form-moduel",
"category": "Form"
},
"publishConfig": {
"access": "public"
},
"license": "MIT",
"homepage": "https://unpkg.com/@yth/[email protected]/build/index.html"
}
참조
1. GitHub - ice-lab/build-scripts: 즉시 사용할 수 있는 프로젝트 솔루션 세트의 신속한 구성을 지원하는 Webpack 기반 플러그인 프로젝트 구성 도구입니다.