Skip to content

Commit 3941bd4

Browse files
authored
Support jvm mem percentage (#3747)
1 parent eeb62d4 commit 3941bd4

File tree

4 files changed

+76
-18
lines changed

4 files changed

+76
-18
lines changed

docs/configuration/jvm-options.md

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ By default, the image declares an initial and maximum Java memory-heap limit of
1010

1111
The values of all three are passed directly to the JVM and support format/units as `<size>[g|G|m|M|k|K]`.
1212

13+
To have control over heap size, without relying on absolute memory sizes percentages are also supported using `<size>%`.
14+
15+
!!! info "RAMPercentage parameters"
16+
Percentage based heap sizing is enabled using `-XX:InitialRAMPercentage` for `INIT_MEMORY` and `-XX:MaxRAMPercentage` for `MAX_MEMORY`.
17+
For details on the function of these parameters look [here](https://www.baeldung.com/java-jvm-parameters-rampercentage).
18+
1319
!!! example "Using docker run"
1420

1521
```
@@ -37,19 +43,7 @@ The values of all three are passed directly to the JVM and support format/units
3743
MAX_MEMORY: 4G
3844
```
3945

40-
To let the JVM calculate the heap size from the container declared memory limit, unset `MEMORY` with an empty value, such as `-e MEMORY=""`. By default, the JVM will use 25% of the container memory limit as the heap limit; however, as an example the following would tell the JVM to use 75% of the container limit of 4GB of memory:
41-
42-
!!! example "MaxRAMPercentage using compose file"
43-
44-
```
45-
environment:
46-
MEMORY: ""
47-
JVM_XX_OPTS: "-XX:MaxRAMPercentage=75"
48-
deploy:
49-
resources:
50-
limits:
51-
memory: 4G
52-
```
46+
To let the JVM calculate the heap size from the container declared memory limit, unset `MEMORY` with an empty value, such as `-e MEMORY=""`. By default, the JVM will use 25% of the container memory limit as the heap limit.
5347

5448
!!! important
5549
The settings above only set the Java **heap** limits. Memory resource requests and limits on the overall container should also account for non-heap memory usage. An extra 25% is [a general best practice](https://dzone.com/articles/best-practices-java-memory-arguments-for-container).

scripts/start-deployBukkitSpigot

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,19 @@ function buildSpigotFromSource {
2828
mkdir ${tempDir}
2929
cd ${tempDir}
3030

31-
jvmOpts="-Xms${INIT_MEMORY:-$MEMORY} -Xmx${MAX_MEMORY:-$MEMORY}"
31+
jvmOpts=""
32+
33+
if isPercentage "${INIT_MEMORY:-$MEMORY}"; then
34+
jvmOpts+="-XX:InitialRAMPercentage=$(getPercentageValue "${INIT_MEMORY:-$MEMORY}") "
35+
else
36+
jvmOpts+="-Xms${INIT_MEMORY:-$MEMORY} "
37+
fi
38+
39+
if isPercentage "${MAX_MEMORY:-$MEMORY}"; then
40+
jvmOpts+="-XX:MaxRAMPercentage=$(getPercentageValue "${MAX_MEMORY:-$MEMORY}")"
41+
else
42+
jvmOpts+="-Xmx${MAX_MEMORY:-$MEMORY}"
43+
fi
3244

3345
logn ''
3446
curl -sSL -o ${tempDir}/BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar && \

scripts/start-finalExec

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,10 +368,15 @@ fi
368368

369369
if [[ ${INIT_MEMORY} || ${MAX_MEMORY} ]]; then
370370
log "Setting initial memory to ${INIT_MEMORY:=${MEMORY}} and max to ${MAX_MEMORY:=${MEMORY}}"
371-
if [[ ${INIT_MEMORY} ]]; then
371+
if isPercentage "$INIT_MEMORY"; then
372+
JVM_OPTS="-XX:InitialRAMPercentage=$(getPercentageValue "${INIT_MEMORY}") ${JVM_OPTS}"
373+
elif [[ ${INIT_MEMORY} ]]; then
372374
JVM_OPTS="-Xms${INIT_MEMORY} ${JVM_OPTS}"
373375
fi
374-
if [[ ${MAX_MEMORY} ]]; then
376+
377+
if isPercentage "$MAX_MEMORY"; then
378+
JVM_OPTS="-XX:MaxRAMPercentage=$(getPercentageValue "${MAX_MEMORY}") ${JVM_OPTS}"
379+
elif [[ ${MAX_MEMORY} ]]; then
375380
JVM_OPTS="-Xmx${MAX_MEMORY} ${JVM_OPTS}"
376381
fi
377382
fi
@@ -431,15 +436,34 @@ elif [[ ${TYPE} == "CURSEFORGE" ]]; then
431436

432437
copyFilesForCurseForge
433438

439+
if isPercentage "$INIT_MEMORY" || isPercentage "$MAX_MEMORY"; then
440+
# Convert to bytes
441+
NORM_INIT_MEM=$(normalizeMemSize "$INIT_MEMORY")
442+
NORM_MAX_MEM=$(normalizeMemSize "$MAX_MEMORY")
443+
# Convert to MB
444+
((NORM_INIT_MEM*=1048576))
445+
((NORM_MAX_MEM*=1048576))
446+
447+
cat > "${FTB_DIR}/settings-local.sh" <<EOF
448+
export MIN_RAM="${NORM_INIT_MEM}M"
449+
export MAX_RAM="${NORM_MAX_MEM}M"
450+
export JAVA_PARAMETERS="${JVM_XX_OPTS} ${JVM_OPTS} $expandedDOpts"
451+
EOF
452+
else
434453
cat > "${FTB_DIR}/settings-local.sh" <<EOF
435454
export MIN_RAM="${INIT_MEMORY}"
436455
export MAX_RAM="${MAX_MEMORY}"
437456
export JAVA_PARAMETERS="${JVM_XX_OPTS} ${JVM_OPTS} $expandedDOpts"
438457
EOF
458+
fi
439459

440460
# patch CurseForge cfg file, if present
441461
if [ -f "${FTB_DIR}/settings.cfg" ] && [[ ${MAX_MEMORY} ]]; then
442-
sed -i "s/MAX_RAM=[^;]*/MAX_RAM=${MAX_MEMORY}/" "${FTB_DIR}/settings.cfg"
462+
if isPercentage "$MAX_MEMORY"; then
463+
sed -i "s/MAX_RAM=[^;]*/MAX_RAM=${NORM_MAX_MEM}M/" "${FTB_DIR}/settings.cfg"
464+
else
465+
sed -i "s/MAX_RAM=[^;]*/MAX_RAM=${MAX_MEMORY}/" "${FTB_DIR}/settings.cfg"
466+
fi
443467
fi
444468

445469
cd "${FTB_DIR}" || (logError "Can't go into ${FTB_DIR}"; exit 1)

scripts/start-utils

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@ function get_major_version() {
3939
echo "$version" | cut -d. -f 1-2
4040
}
4141

42+
function isPercentage() {
43+
local value=$1
44+
45+
[[ $value =~ ^[0-9]+(\.[0-9]+)?\s*%$ ]]
46+
}
47+
48+
function getPercentageValue() {
49+
local value=$1
50+
if [[ "$value" =~ ^([0-9]+(\.[0-9]+)?)\s*%$ ]]; then
51+
echo "${BASH_REMATCH[1]}"
52+
return 0
53+
else
54+
logError "Value '$value' is not a valid percentage."
55+
return 1
56+
fi
57+
}
58+
4259
function isURL() {
4360
local value=$1
4461

@@ -229,6 +246,7 @@ function logRcon() {
229246

230247
function normalizeMemSize() {
231248
local scale=1
249+
local mem=1
232250
case ${1,,} in
233251
*k)
234252
scale=1024
@@ -239,10 +257,20 @@ function normalizeMemSize() {
239257
*g)
240258
scale=1073741824
241259
;;
260+
*%)
261+
# Get system memory
262+
if [ -f "/sys/fs/cgroup/memory/memory.limit_in_bytes" ]; then
263+
mem=$( cat /sys/fs/cgroup/memory/memory.limit_in_bytes )
264+
elif [ -f "/sys/fs/cgroup/memory.max" ]; then
265+
mem=$( cat /sys/fs/cgroup/memory.max )
266+
fi
267+
# Scale is used to transform percentages into decimals (eg. 60 -> 0.6)
268+
scale=0.01
269+
;;
242270
esac
243271

244272
val=${1:0:-1}
245-
echo $((val * scale))
273+
echo $((val * scale * mem))
246274
}
247275

248276
function compare_version() {

0 commit comments

Comments
 (0)