https://github.com/softleader/memory-calculator
JVM Memory Calculator
https://github.com/softleader/memory-calculator
jib jib-maven-plugin jvm libjvm memory memory-calculator
Last synced: 2 months ago
JSON representation
JVM Memory Calculator
- Host: GitHub
- URL: https://github.com/softleader/memory-calculator
- Owner: softleader
- License: apache-2.0
- Created: 2023-12-29T07:07:47.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-12-10T09:41:52.000Z (6 months ago)
- Last Synced: 2025-03-24T14:44:34.072Z (3 months ago)
- Topics: jib, jib-maven-plugin, jvm, libjvm, memory, memory-calculator
- Language: Go
- Homepage:
- Size: 201 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://goreportcard.com/report/github.com/softleader/memory-calculator)

[](./LICENSE)
[](https://github.com/softleader/memory-calculator/actions)
[](https://github.com/softleader/memory-calculator/releases)
# 記憶體計算工具(Memory Calculator)
**記憶體計算工具** 是為了協助 Java
虛擬機(JVM)在運行時計算記憶體設定而開發的工具,基於 [paketo-buildpacks/libjvm](https://github.com/paketo-buildpacks/libjvm/)。## Calculation Algorithm
### 基本計算公式
JVM 記憶體的計算公式如下:
```markdown
Heap = Total Container Memory - Non-Heap - Headroom
```- **Total Container Memory**: 應用程式可用的總記憶體,通常是 Container 設置的記憶體上限值
- **Non-Heap Memory**: Non-Heap 記憶體,詳細於後面說明
- **Headroom**: Container 總記憶體的一定比例,用於非 JVM 的操作。預設值為 0。### Non-Heap 記憶體計算
Non-Heap Memory 的計算公式如下:
```markdown
Non-Heap = Direct Memory + Metaspace + Reserved Code Cache + (Thread Stack * Thread Count)
```下表列出了各個參數對應的 JVM Falg 及其預設值:
| 記憶體區域 | JVM Flag | Default |
|-----------|----------|---------|
| Direct Memory | `-XX:MaxDirectMemorySize` | 10MB(JVM Default) |
| Metaspace | `-XX:MaxMetaspaceSize` | 基於 Class 計數自動計算 |
| Reserved Code Cache | `-XX:ReservedCodeCacheSize` | 240MB(JVM Default) |
| Thread Stack | `-Xss` | 1M * 250(JVM Default Thread Stack 大小 * Tomcat 預設的最佳 Thread Count) |### 結果與應用
- 在計算完上述各值後,剩餘的記憶體將被分配給 `-Xmx` Flag,作為 JVM 的 Heap 記憶體
- 所有 Flag 和值將被放到 `JAVA_TOOL_OPTIONS` Flag 中,讓應用程式使用若你想獲得更深入或更完整的說明,請點選以下連結:[Java Buildpack - Memory Calculator](https://paketo.io/docs/reference/java-reference/#memory-calculator)
## Input Variables
在計算過程中,需要依照特定的順序和邏輯使用多個參數,以下是參數的取得順序及其說明:
| 參數說明 | 優先判斷 args 傳入 | 其次判斷 OS Variable | 最後的預設值或行為 |
|---|---|---|---|
| 記憶體計算工具分配的預留空間百分比 | `--head-room` | `$BPL_JVM_HEAD_ROOM` | `0` |
| 運行時的用戶線程數 | `--thread-count` | `$BPL_JVM_THREAD_COUNT` | `200` |
| 運行時將加載的 class 數量 | `--loaded-class-count` | `$BPL_JVM_LOADED_CLASS_COUNT` | 若沒提供,則以 App 目錄,JVM class 數量,JVM class 數量調整,於啟動時動態的計算出建議值 |
| App 目錄 | `--app-path` | `$BPI_APPLICATION_PATH` | `/app` |
| JVM class 數量 | `--jvm-class-count` | `$BPI_JVM_CLASS_COUNT` | 若沒提供,則動態計算 `$JAVA_HOME` 下的 class 數量 |
| JVM class 數量調整 | `--jvm-class-adj` | `$BPL_JVM_CLASS_ADJUSTMENT` | 無,可接受數字 (`1000`) 或百分比 (`150%`) |
| JVM CA 目錄 | `--jvm-cacerts` | `$BPI_JVM_CACERTS` | 若沒提供,則試著使用 `$JAVA_HOME/lib/security/cacerts` |
| Java 啟動參數 | `--jvm-options` | `$JAVA_OPTS` | |
| 是否啟用 [JDWP](https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/introclientissues005.html) | `--enable-jdwp` | `$BPL_DEBUG_ENABLED` | `true` |
| 是否啟用 [NMT](https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html) | `--enable-nmt` | `$BPL_JAVA_NMT_ENABLED` | `false` |
| 是否啟用 [JFR](https://docs.oracle.com/javacomponents/jmc-5-4/jfr-runtime-guide/about.htm) | `--enable-jfr` | `$BPL_JFR_ENABLED` | `false` |
| 是否啟用 [JMX](https://www.oracle.com/java/technologies/javase/javamanagement.html) | `--enable-jmx` | `$BPL_JMX_ENABLED` | `false` |執行以下指令以查看完整的 args 參數說明:
```sh
memory-calculator -h
```## Entrypoint
[`entrypoint.sh`](./entrypoint.sh) 是一個專為使用 [Jib](https://github.com/GoogleContainerTools/jib) 打包的 Image 而設計的進入點,它在執行時會根據前面提到的 [計算演算法](#calculation-algorithm) 來計算出建議的記憶體配置,然後啟動 Java 應用程式。
使用 `entrypoint.sh` 的步驟如下:
1. 將 `entrypoint.sh` 放入 Jib 所使用的 Base Image 中,例如放在 `/tmp` 資料夾下。
2. 在 Jib 的配置中,將 entrypoint 設定為 `/tmp/entrypoint.sh`。在 Jib 中若 [自定義了 entrypoint](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#custom-container-entrypoint),`` 參數將無法被直接引用。因此,`entrypoint.sh` 還整合了另一套 Jib 擴充工具: [jib-jvm-flags-extension-maven](https://github.com/softleader/jib-jvm-flags-extension-maven)。藉由這個 Jib Extension,我們就可以繼續使用 ``。
### 支援的參數
`entrypoint.sh` 支援以下作業系統環境變數:
- `MEM_CALC_HOME`:用於設定執行檔的目錄,預設值為: `/usr/local/bin`。
- `MEM_CALC_ENABLED`:預設為 `true`,若將此值設為 `false`,則會跳過記憶體計算,直接啟動 Java 應用程式。
- `MEM_CALC_DEBUG`:除錯模式,預設為 `false`,若將此值設為 `true`,則會列印出計算過程中除錯訊息,及啟動 Java 應用程式的完整指令。## 開發前準備
- Golang: v1.22+
- Jib ContainerTool
- Linux 基礎映像