You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2020/01/24 17:09:08 UTC
[camel-k] 07/07: feat(JVM): Max heap size heuristic based on
container memory limit
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 <an...@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)