angular / angular-cli

CLI tool for Angular
https://cli.angular.dev
MIT License
26.78k stars 11.98k forks source link

Node process for "Build" command is taking much more RAM (6GB) than configured "max_old_space_size" option (4GB) (Angular 15) #26885

Closed sangalao closed 10 months ago

sangalao commented 10 months ago

Command

build

Is this a regression?

The previous version in which this bug was not present was

No response

Description

Hello,

The build command I run for my project is :

node --max_old_space_size=4096 node_modules/@angular/cli/bin/ng build --configuration production

This commands runs successfully, but however the NodeJS process for building app takes up to 10GB.

To be more precise, during beginning-middle of building phase it takes less than 4GB, and always at the middle-end of building phase, it goes up to 10GB just before end of successful build.

To start investigation, I launched build command with "-trace-gc" option :

node --trace-gc --max_old_space_size=4096 node_modules/@angular/cli/bin/ng build --configuration production

I saw, with this option, that there are several Node "V8 isolates" that are created in the same NodeJS process ("V8 isolate" = JS Heap instance, based on Node GC documentation) :

Among those "V8 isolates", with a proper heap for each, 2 of them have particular high heap amount at the same time :

What also have to be noticed is that the second one consumes such a memory ONLY when option "production > optimization > scripts" in "angular.json" is set to true. The "production > optimization > scripts" option in "angular.json" is required for my production performance requirements (minification, tree-shaking, dead-code elimination).

So my questions/remarks are :

Thanks

Note : I was also facing same issue with Angular 14 : https://github.com/angular/angular-cli/issues/26553

Minimal Reproduction

Command run :

node --max_old_space_size=4096 node_modules/@angular/cli/bin/ng build --configuration production

Packages :

  "dependencies": {
    "@angular/animations": "~15.2.10",
    "@angular/cdk": "~15.2.9",
    "@angular/cdk-experimental": "~15.2.9",
    "@angular/common": "~15.2.10",
    "@angular/compiler": "~15.2.10",
    "@angular/core": "~15.2.10",
    "@angular/flex-layout": "^15.0.0-beta.42",
    "@angular/forms": "~15.2.10",
    "@angular/material": "~15.2.9",
    "@angular/material-moment-adapter": "~15.2.9",
    "@angular/platform-browser": "~15.2.10",
    "@angular/platform-browser-dynamic": "~15.2.10",
    "@angular/router": "~15.2.10",
    "@dashjoin/json-schema-form": "1.0.1",
    "jsonata": "^2.0.2",
    "apache-arrow": "14.0.1",
    "@danmarshall/deckgl-typings": "4.9.12",
    "@deck.gl/aggregation-layers": "8.7.7",
    "@deck.gl/core": "8.7.7",
    "@deck.gl/extensions": "8.7.7",
    "@deck.gl/geo-layers": "8.7.7",
    "@deck.gl/json": "8.7.7",
    "@deck.gl/layers": "8.7.7",
    "@deck.gl/mapbox": "8.7.7",
    "@deck.gl/mesh-layers": "8.7.7",
    "@loaders.gl/core": "3.4.14",
    "@loaders.gl/draco": "3.4.14",
    "@loaders.gl/gltf": "3.4.14",
    "@loaders.gl/worker-utils": "3.4.14",
    "@luma.gl/constants": "8.5.10",
    "@luma.gl/core": "8.5.10",
    "@mapbox/mapbox-gl-draw": "^1.2.0",
    "@nebula.gl/layers": "nebula.gl__layers@^1.0.3-rev-2",
    "@nebula.gl/overlays": "1.0.4",
    "@ngx-translate/core": "^14.0.0",
    "@ngx-translate/http-loader": "^7.0.0",
    "@turf/along": "6.3.0",
    "@turf/destination": "6.3.0",
    "@turf/distance": "6.3.0",
    "@turf/helpers": "6.3.0",
    "@turf/length": "6.3.0",
    "@turf/boolean-contains": "6.3.0",
    "@turf/area": "6.3.0",
    "@turf/rewind": "6.3.0",
    "angular-oauth2-oidc": "^13.0.1",
    "angular-oauth2-oidc-jwks": "^13.0.1",
    "aws-sdk": "^2.1104.0",
    "bpmn-js": "^11.5.0",
    "chroma-js": "2.1.0",
    "core-js": "^3.21.1",
    "css-loader": "^6.7.1",
    "csscolorparser": "1.0.3",
    "diagram-js": "^11.11.0",
    "echarts": "^5.4.0",
    "file-saver": "^2.0.2",
    "golden-layout": "^1.5.9",
    "html2canvas": "1.3.2",
    "ip-address": "5.9.0",
    "jquery": "^3.4.1",
    "jsep": "0.3.4",
    "jsoneditor": "^9.1.4",
    "jspdf": "^2.1.1",
    "jspdf-autotable": "^3.5.14",
    "jszip": "^3.10.1",
    "lodash": "^4.17.21",
    "mapbox-gl": "1.13.2",
    "moment": "^2.29.1",
    "mqtt": "4.3.7",
    "ng5-slider": "^1.2.4",
    "ngx-color": "^5.1.4",
    "ngx-echarts": "^14.0.0",
    "ngx-material-timepicker": "^5.5.3",
    "ngx-mqtt": "9.0.5",
    "ngx-papaparse": "^4.0.4",
    "ngx-quill-upload": "^2.0.0",
    "ngx-scrollbar": "^7.4.1",
    "ngx-ui-loader": "^13.0.0",
    "object-hash": "3.0.0",
    "primeicons": "^6.0.1",
    "primeng": "~15.2.0",
    "patch-package": "^8.0.0",
    "quill": "quill@2.0.0-dev.4-rev-1",
    "quill-better-table": "quill-better-table@1.2.10-rev-1",
    "quill-blot-formatter": "quill-blot-formatter@1.0.5-rev-1",
    "quill-delta": "quill-delta@5.0.0-rev-1",
    "roboto-fontface": "^0.10.0",
    "rxjs": "~7.5.0",
    "rxjs-compat": "^6.6.7",
    "stream": "0.0.2",
    "supercluster": "7.1.3",
    "three": "^0.131.3",
    "timers": "^0.1.1",
    "tslib": "^2.3.0",
    "util": "^0.12.4",
    "uuid": "8.3.2",
    "vis-timeline": "7.7.3",
    "vis-data": "7.1.9",
    "vis-util": "5.0.7",
    "xml2js": "^0.4.23",
    "zone.js": "~0.11.4"
  },

Exception or Error

No response

Your Environment

_                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / Γû│ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/

Angular CLI: 15.1.6
Node: 16.19.0
Package Manager: npm 8.19.3
OS: win32 x64

Angular: 15.2.10
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.1501.6
@angular-devkit/build-angular      15.1.6
@angular-devkit/core               15.1.6
@angular-devkit/schematics         15.1.6
@angular/cdk                       15.2.9
@angular/cdk-experimental          15.2.9
@angular/cli                       15.1.6
@angular/flex-layout               15.0.0-beta.42
@angular/material                  15.2.9
@angular/material-moment-adapter   15.2.9
@schematics/angular                15.1.6
rxjs                               7.5.7
typescript                         4.9.5

Anything else relevant?

No response

alan-agius4 commented 10 months ago

The "max_old_space_size" parameter seems to mainly apply to the MAIN V8 isolate, so I'm not able to configure "global" memory consumption during build phase. Is there a parameter to configure the GLOBAL heap used by NodeJS process for building phase ? If not, I think it could be useful to have one, and/or be able to fine-tune memory for all V8 isolates with high memory consumption

No, Node.js does not provide a global way of doing so. What you can do however is use NG_BUILD_MAX_WORKERS to reduce the number of workers used at the cost of increasing the build time.

I cannot find any documentation explaning the fact that "production > optimization > scripts" option can result in high memory consumption, why it takes such memory, how I could tune it. Is is possible to have such a documentation / explanation ?

This is expected when using the Webpack and terser build pipeline, three-shaking and dead code elimination are resource intensive tasks that lead to increased in memory and CPU usage. There are no settings to fine-tune this or reduce the memory usage.

I also found this issue about memory limits for several "V8 isolates" in NodeJS, and was wondering whether it could be linked to my issue : https://github.com/nodejs/node/issues/43991

No really, as that issues mentions that max_old_space_size is overridding the resourceLimits.maxOldSpaceSizeMb that is passed to each worker which we do not use.


I am not seeing anything that is actionable from our end here.

angular-automatic-lock-bot[bot] commented 9 months ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.