前言
前陣子在處理 Jenkins 的 Automation,在 build Angular 專案時發生了 Heap out of memory 的問題,稍微看了下要怎麼解決,還有發生的原因可能是什麼
1 | FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory |
簡單的解決方式
簡單的方法就是在執行 ng build
時增加 default build heap size
1 | node --max-old-space-size=<size-you-want> node_modules/@angular/cli/bin/ng build <your-app-module> --prod |
要注意的是 @angular/cli/bin/ng
的路徑是不是你目前要 build 的 app 使用的,有可能在外層,看你環境的設定
可以把這段加到 package.json 的 scripts 方便執行
可能的原因
RAM
最直觀的原因就是機器的 memory 不夠使用
這個 issue 是在 Windows VM 上跑多個 Jenkins Job 發生的,在多數 local build 的情況並沒有遇過,甚至在跑更多 Job 的 Linux server 也沒碰過
後來去看了下該機器的 RAM,原來只有 4GB…?
現在大部分人的筆電至少都配有 8GB,桌電的話更是 16 GB 起跳,所以團隊幾乎沒人遇過 out of memory 的 build error
V8 Engine 限制
再來可能的就是專案在開發時 Module 越來越肥大,需要 Build 的 js 佔用太多動態記憶體,而 NodeJS builder 是採用 V8 Engine,和 Google Chrome 一樣
V8 Engine 預設給 heap size 的大小限制是
- 32 bit 的平台為 0.7 GB
- 64 bit 的平台為 1.4 GB
所以一但超過 V8 預設的記憶體限制,build 就會終止,為了是不要讓 NodeJS 使用太多系統的記憶體 (但 Chrome 還是用得很兇欸..?)
NodeJS 12
好消息是在 NodeJS 12 的 intro 中有提到,已經拿掉預設的 heap limits,改成是 config 目前可用的 memory
This update will configure the JavaScript heap size based on available memory instead of using defaults that were set by V8 for use with browsers. In previous releases, unless configured, V8 defaulted to limiting the max heap size to 700 MB or 1400MB on 32 and 64-bit platforms respectively. Configuring the heap size based on available memory ensures that Node.js does not try to use more memory than is available and terminating when its memory is exhausted.
This is particularly useful when processing large data-sets. As before, it will still be possible to set — max-old-space-size to use a different limit if the default is not appropriate for your application.
在這個 Angular Github thread 中也有提到這件事,說升級到 Node 12 就解決
但底下有個人說使用 Node 12 還是有一樣的問題,這可能就要再深入看看為什麼,不過目前專案改成使用 Node 12+ 的版本後,我在 RAM 很小的 Windows VM 上跑 Jenkins 沒再遇過 Heap out of memory 了
後記
做個簡單紀錄,真正的原因我還是不能確定是什麼XD,一開始先用了 max size 安然跑了兩個月,後來在測試一些情況時不小心把 max size 移掉後才發現沒有這問題了,而最近才讀到原來 Node 12+ 有改善這件事,所以才想到也許是跟專案前個月開始升成使用 Node 12+ 有關,回頭審視了下當初的問題
有關於 OS & memory 的坑真的很深,或許日後有更多這方面的經驗跟心得再說說(通常這麼說就是不會有)