This is an automated email from the ASF dual-hosted git repository. astefanutti pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 22fe7285a8adb24159a970a9e0d57da78bb84813 Author: Antonin Stefanutti <anto...@stefanutti.fr> AuthorDate: Fri Jan 24 16:31:16 2020 +0100 feat(JVM): Max heap size heuristic based on container memory limit --- go.mod | 1 + pkg/trait/jvm.go | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/go.mod b/go.mod index ac7aa1e..07f35d9 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( github.com/stoewer/go-strcase v1.0.2 github.com/stretchr/testify v1.4.0 go.uber.org/multierr v1.1.0 + gopkg.in/inf.v0 v0.9.1 gopkg.in/yaml.v2 v2.2.4 k8s.io/api v0.0.0 k8s.io/apimachinery v0.0.0 diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go index b1a783b..89f3710 100644 --- a/pkg/trait/jvm.go +++ b/pkg/trait/jvm.go @@ -22,9 +22,14 @@ import ( "sort" "strings" + "gopkg.in/inf.v0" + "github.com/pkg/errors" "github.com/scylladb/go-set/strset" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + k8sclient "sigs.k8s.io/controller-runtime/pkg/client" v1 "github.com/apache/camel-k/pkg/apis/camel/v1" @@ -125,11 +130,32 @@ func (t *jvmTrait) Apply(e *Environment) error { suspend, t.DebugAddress)) } + hasHeapSizeOption := false // Add JVM options if t.Options != nil { + hasHeapSizeOption = strings.Contains(*t.Options, "-Xmx") || + strings.Contains(*t.Options, "-XX:MaxHeapSize") || + strings.Contains(*t.Options, "-XX:MinRAMPercentage") || + strings.Contains(*t.Options, "-XX:MaxRAMPercentage") + container.Args = append(container.Args, strings.Split(*t.Options, ",")...) } + // Tune JVM maximum heap size based on the container memory limit, if any. + // This is configured off-container, thus is limited to explicit user configuration. + // We may want to inject a wrapper script into the container image, so that it can + // be performed in-container, based on CGroups memory resource control files. + if memory, hasLimit := container.Resources.Limits[corev1.ResourceMemory]; !hasHeapSizeOption && hasLimit { + // Simple heuristic that caps the maximum heap size to 50% of the memory limit + percentage := int64(50) + // Unless the memory limit is lower than 300M, in which case we leave more room for the non-heap memory + if resource.NewScaledQuantity(300, 6).Cmp(memory) > 0 { + percentage = 25 + } + memory.AsDec().Mul(memory.AsDec(), inf.NewDec(percentage, 2)) + container.Args = append(container.Args, fmt.Sprintf("-Xmx%dM", memory.ScaledValue(resource.Mega))) + } + // Add mounted resources to the class path for _, m := range container.VolumeMounts { classpath.Add(m.MountPath)