Skip to content

Commit f0763af

Browse files
authored
Auto-configure default JVM Xmx based on workspace resources (#20536)
* Auto-configure default JVM Xmx based on workspace resources * Add max xmx and unit tests
1 parent 4d3cca4 commit f0763af

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

components/ide/jetbrains/launcher/main.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ import (
4242
supervisor "github.com/gitpod-io/gitpod/supervisor/api"
4343
)
4444

45-
const defaultBackendPort = "63342"
45+
const (
46+
defaultBackendPort = "63342"
47+
maxDefaultXmx = 8 * 1024
48+
minDefaultXmx = 2 * 1024
49+
)
4650

4751
var (
4852
// ServiceName is the name we use for tracing/logging.
@@ -857,6 +861,19 @@ func updateVMOptions(
857861
if err == nil && parsedCPUCount > 0 && parsedCPUCount <= 16 {
858862
gitpodVMOptions = append(gitpodVMOptions, "-XX:ActiveProcessorCount="+cpuCount)
859863
}
864+
865+
memory := os.Getenv("GITPOD_MEMORY")
866+
parsedMemory, err := strconv.Atoi(memory)
867+
if err == nil && parsedMemory > 0 {
868+
xmx := (float64(parsedMemory) * 0.6)
869+
if xmx > maxDefaultXmx { // 8G
870+
xmx = maxDefaultXmx
871+
}
872+
if xmx > minDefaultXmx {
873+
gitpodVMOptions = append(gitpodVMOptions, fmt.Sprintf("-Xmx%dm", int(xmx)))
874+
}
875+
}
876+
860877
vmoptions := deduplicateVMOption(ideaVMOptionsLines, gitpodVMOptions, filterFunc)
861878

862879
// user-defined vmoptions (EnvVar)

components/ide/jetbrains/launcher/main_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,12 @@ func TestUpdateVMOptions(t *testing.T) {
5454
{"idea64.vmoptions (INTELLIJ_VMOPTIONS env set)", "intellij", map[string]string{"INTELLIJ_VMOPTIONS": "-Xmx4096m"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx4096m\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true"},
5555
{"idea64.vmoptions (INTELLIJ_VMOPTIONS env set)", "intellij", map[string]string{"INTELLIJ_VMOPTIONS": "-Xmx4096m -XX:MaxRAMPercentage=75"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx4096m\n-XX:MaxRAMPercentage=75\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true"},
5656
{"goland64.vmoptions (GOLAND_VMOPTIONS env set with conflicting options)", "goland", map[string]string{"GOLAND_VMOPTIONS": "-ea -XX:+IgnoreUnrecognizedVMOptions -XX:MaxRAMPercentage=75 -XX:MaxRAMPercentage=50"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-ea\n-XX:+IgnoreUnrecognizedVMOptions\n-XX:+UseContainerSupport\n-XX:MaxRAMPercentage=50"},
57+
{"GITPOD_MEMORY with 1G", "intellij", map[string]string{"GITPOD_MEMORY": "1024"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true\n-XX:+UseContainerSupport\n"},
58+
{"GITPOD_MEMORY with 4G", "intellij", map[string]string{"GITPOD_MEMORY": "4096"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx2457m\n-Dsun.tools.attach.tmp.only=true\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true\n-XX:+UseContainerSupport\n"},
59+
{"GITPOD_MEMORY with 256G will use max 8G", "intellij", map[string]string{"GITPOD_MEMORY": "262144"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx8192m\n-Dsun.tools.attach.tmp.only=true\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true\n-XX:+UseContainerSupport\n"},
5760
}
61+
os.Unsetenv("GITPOD_CPU_COUNT")
62+
os.Unsetenv("GITPOD_MEMORY")
5863
for _, test := range tests {
5964
// compare vmoptions string content equality (i.e. split into slices and compare ignore order)
6065
lessFunc := func(a, b string) bool { return a < b }

components/ws-manager-mk2/controllers/create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ func createWorkspaceEnvironment(sctx *startWorkspaceContext) ([]corev1.EnvVar, e
612612
if err != nil {
613613
return nil, xerrors.Errorf("cannot create environment: %w", err)
614614
}
615-
memoryInMegabyte := res.Memory().Value() / (1000 * 1000)
615+
memoryInMegabyte := res.Memory().Value() / (1024 * 1024)
616616
result = append(result, corev1.EnvVar{Name: "GITPOD_MEMORY", Value: strconv.FormatInt(memoryInMegabyte, 10)})
617617

618618
cpuCount := res.Cpu().Value()

dev/preview/workflow/preview/deploy-gitpod.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,13 @@ yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].descr
208208
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].powerups "2"
209209
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[1].credits.perMinute "0.1666666667"
210210

211+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[+].id "g1-large"
212+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[2].category "GENERAL PURPOSE"
213+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[2].displayName "Large"
214+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[2].description "Large workspace class (50GB disk)"
215+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[2].powerups "3"
216+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.webapp.workspaceClasses[2].credits.perMinute "0.5"
217+
211218
# create two workspace classes (g1-standard and g1-small) in ws-manager configmap
212219
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.workspace.classes["g1-standard"].name "g1-standard"
213220
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.workspace.classes["g1-standard"].resources.requests.cpu "100m"
@@ -221,6 +228,11 @@ yq w -i "${INSTALLER_CONFIG_PATH}" experimental.workspace.classes["g1-small"].re
221228
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.workspace.classes["g1-small"].resources.limits.storage "5Gi"
222229
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.workspace.classes["g1-small"].resources.limits.ephemeral-storage "5Gi"
223230

231+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.workspace.classes["g1-large"].name "g1-large"
232+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.workspace.classes["g1-large"].resources.requests.cpu "100m"
233+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.workspace.classes["g1-large"].resources.requests.memory "16Gi"
234+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.workspace.classes["g1-large"].resources.limits.storage "50Gi"
235+
yq w -i "${INSTALLER_CONFIG_PATH}" experimental.workspace.classes["g1-large"].resources.limits.ephemeral-storage "50Gi"
224236
#
225237
# configureObjectStorage
226238
#

0 commit comments

Comments
 (0)