summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArne Juul <arnej@yahooinc.com>2022-11-09 09:00:53 +0000
committerArne Juul <arnej@yahooinc.com>2022-11-09 09:36:46 +0000
commit29043ae1e3e79ca3587d2311d0276dba0979a406 (patch)
treee82de066a5e0a51865e950c96ddc41f446f95bda
parentbccc424f69dc1748813bc3d3b5f87fdc9ba1ed16 (diff)
use new memory abstraction
-rw-r--r--client/go/jvm/application_container.go12
-rw-r--r--client/go/jvm/mem_avail.go22
-rw-r--r--client/go/jvm/mem_options.go80
-rw-r--r--client/go/jvm/mem_options_test.go15
-rw-r--r--client/go/jvm/options_test.go63
5 files changed, 94 insertions, 98 deletions
diff --git a/client/go/jvm/application_container.go b/client/go/jvm/application_container.go
index 081dc96c5a4..14efbe65e33 100644
--- a/client/go/jvm/application_container.go
+++ b/client/go/jvm/application_container.go
@@ -74,6 +74,10 @@ func (a *ApplicationContainer) addJdiscProperties() {
}
+func validPercentage(val int) bool {
+ return val > 0 && val < 100
+}
+
func (a *ApplicationContainer) configureMemory(qc *QrStartConfig) {
jvm_heapsize := qc.Jvm.Heapsize // Heap size (in megabytes) for the Java VM
jvm_minHeapsize := qc.Jvm.MinHeapsize // Min heapsize (in megabytes) for the Java VM
@@ -90,10 +94,10 @@ func (a *ApplicationContainer) configureMemory(qc *QrStartConfig) {
if jvm_minHeapsize <= 0 {
jvm_minHeapsize = jvm_heapsize
}
- available := getAvailableMbOfMemory()
- if jvm_heapSizeAsPercentageOfPhysicalMemory > 0 && jvm_heapSizeAsPercentageOfPhysicalMemory < 100 && available > 0 {
+ available := getAvailableMemory()
+ if validPercentage(jvm_heapSizeAsPercentageOfPhysicalMemory) && available.ToMB() > 500 {
available = adjustAvailableMemory(available)
- jvm_heapsize = available * jvm_heapSizeAsPercentageOfPhysicalMemory / 100
+ jvm_heapsize = available.ToMB() * jvm_heapSizeAsPercentageOfPhysicalMemory / 100
}
if jvm_minHeapsize > jvm_heapsize {
trace.Warning(fmt.Sprintf(
@@ -119,7 +123,7 @@ func (a *ApplicationContainer) configureMemory(qc *QrStartConfig) {
opts.AddOption(fmt.Sprintf("-Xmx%dm", jvm_heapsize))
opts.AddOption(fmt.Sprintf("-XX:ThreadStackSize=%d", jvm_stacksize))
opts.AddOption(fmt.Sprintf("-XX:MaxDirectMemorySize=%dm", maxDirectMemorySize))
- opts.MaybeAddHugepages(jvm_heapsize)
+ opts.MaybeAddHugepages(MegaBytesOfMemory(jvm_heapsize))
if jvm_compressedClassSpaceSize > 0 {
opts.AddOption(fmt.Sprintf("-XX:CompressedClassSpaceSize=%dm", jvm_compressedClassSpaceSize))
}
diff --git a/client/go/jvm/mem_avail.go b/client/go/jvm/mem_avail.go
index 4447bd8d2f0..78627a9b7bb 100644
--- a/client/go/jvm/mem_avail.go
+++ b/client/go/jvm/mem_avail.go
@@ -13,19 +13,19 @@ import (
"github.com/vespa-engine/vespa/client/go/util"
)
-func parseFree(txt string) int {
+func parseFree(txt string) AmountOfMemory {
f := strings.Fields(txt)
for idx, field := range f {
if field == "Mem:" && idx+1 < len(f) {
res, err := strconv.Atoi(f[idx+1])
if err == nil {
- return res
+ return MegaBytesOfMemory(res)
} else {
trace.Warning(err)
}
}
}
- return 0
+ return BytesOfMemory(0)
}
func parentDir(dir string) string {
@@ -74,8 +74,8 @@ func vespa_cg2get(filename string) (output string, err error) {
return min_value, nil
}
-func getAvailableMbOfMemory() int {
- result := 0
+func getAvailableMemory() AmountOfMemory {
+ result := BytesOfMemory(0)
backticks := util.BackTicksWithStderr
freeOutput, err := backticks.Run("free", "-m")
if err == nil {
@@ -84,7 +84,7 @@ func getAvailableMbOfMemory() int {
} else {
trace.Trace("run 'free' failed:", err)
}
- available_cgroup := int(1 << 31)
+ available_cgroup := KiloBytesOfMemory(1 << 31)
cggetOutput, err := backticks.Run("cgget", "-nv", "-r", "memory.limit_in_bytes", "/")
if err != nil {
if strings.Contains(cggetOutput, "Cgroup is not mounted") {
@@ -96,16 +96,16 @@ func getAvailableMbOfMemory() int {
trace.Debug("run 'cgget' failed:", err, "=>", cggetOutput)
}
if err == nil && cggetOutput != "max" {
- numBytes, err := strconv.Atoi(cggetOutput)
- if err == nil && numBytes > PowerOfTwo10 {
- available_cgroup = numBytes / PowerOfTwo10
+ numBytes, err := strconv.ParseInt(cggetOutput, 10, 64)
+ if err == nil && numBytes > (1<<28) {
+ available_cgroup = AmountOfMemory{numBytes: numBytes}
} else {
trace.Warning("unexpected 'cgget' output:", cggetOutput)
}
}
- if result == 0 || result > available_cgroup {
+ if result.ToKB() == 0 || result.ToKB() > available_cgroup.ToKB() {
result = available_cgroup
}
- trace.Trace("getAvailableMbOfMemory returns:", result)
+ trace.Trace("getAvailableMemory returns:", result)
return result
}
diff --git a/client/go/jvm/mem_options.go b/client/go/jvm/mem_options.go
index 4c708bc526a..a2be6ac7b26 100644
--- a/client/go/jvm/mem_options.go
+++ b/client/go/jvm/mem_options.go
@@ -11,77 +11,59 @@ import (
"github.com/vespa-engine/vespa/client/go/util"
)
-const (
- PowerOfTwo10 = 1 << 10
-)
-
-func (opts *Options) getOrSetHeapMb(prefix string, heapMb int) int {
+func (opts *Options) getOrSetHeapSize(prefix string, heapSize AmountOfMemory) AmountOfMemory {
var missing bool = true
for _, x := range opts.jvmArgs {
if strings.HasPrefix(x, prefix) {
- var val int
- var suffix rune
- n, err := fmt.Sscanf(x, prefix+"%d%c", &val, &suffix)
- if n == 2 && err == nil {
+ val, err := ParseJvmMemorySpec(strings.TrimPrefix(x, prefix))
+ if err == nil {
missing = false
- switch suffix {
- case 'k':
- heapMb = val / PowerOfTwo10
- case 'm':
- heapMb = val
- case 'g':
- heapMb = val * PowerOfTwo10
- default:
- missing = true
- }
+ heapSize = val
}
}
}
if missing {
- suffix := "m"
- newVal := heapMb
- if (newVal % PowerOfTwo10) == 0 {
- suffix = "g"
- newVal /= PowerOfTwo10
- }
- opts.AppendOption(fmt.Sprintf("%s%d%s", prefix, newVal, suffix))
+ opts.AppendOption(fmt.Sprintf("%s%s", prefix, heapSize.AsJvmSpec()))
}
- return heapMb
+ return heapSize
}
-func (opts *Options) CurMinHeapMb(fallback int) int {
- return opts.getOrSetHeapMb("-Xms", fallback)
+func (opts *Options) CurMinHeapSize(fallback AmountOfMemory) AmountOfMemory {
+ return opts.getOrSetHeapSize("-Xms", fallback)
}
-func (opts *Options) CurMaxHeapMb(fallback int) int {
- return opts.getOrSetHeapMb("-Xmx", fallback)
+func (opts *Options) CurMaxHeapSize(fallback AmountOfMemory) AmountOfMemory {
+ return opts.getOrSetHeapSize("-Xmx", fallback)
}
-func (opts *Options) AddDefaultHeapSizeArgs(minHeapMb, maxHeapMb int) {
- trace.Trace("AddDefaultHeapSizeArgs", minHeapMb, "/", maxHeapMb)
- minHeapMb = opts.CurMinHeapMb(minHeapMb)
- maxHeapMb = opts.CurMaxHeapMb(maxHeapMb)
- opts.MaybeAddHugepages(maxHeapMb)
+func (opts *Options) AddDefaultHeapSizeArgs(minHeapSize, maxHeapSize AmountOfMemory) {
+ trace.Trace("AddDefaultHeapSizeArgs", minHeapSize, "/", maxHeapSize)
+ minHeapSize = opts.CurMinHeapSize(minHeapSize)
+ maxHeapSize = opts.CurMaxHeapSize(maxHeapSize)
+ opts.MaybeAddHugepages(maxHeapSize)
}
-func (opts *Options) MaybeAddHugepages(maxHeapMb int) {
- thpSizeMb := util.GetThpSizeMb()
- if thpSizeMb*2 < maxHeapMb {
- trace.Trace("add UseTransparentHugePages, thpSize", thpSizeMb, "* 2 < maxHeap", maxHeapMb)
+func (opts *Options) MaybeAddHugepages(maxHeapSize AmountOfMemory) {
+ thpSizeSize := util.GetThpSizeMb()
+ heapSize := maxHeapSize.ToMB()
+ if thpSizeSize*2 < heapSize {
+ trace.Trace("add UseTransparentHugePages, thpSize", thpSizeSize, "* 2 < maxHeap", heapSize)
opts.AddOption("-XX:+UseTransparentHugePages")
} else {
- trace.Trace("no UseTransparentHugePages, thpSize", thpSizeMb, "* 2 >= maxHeap", maxHeapMb)
+ trace.Trace("no UseTransparentHugePages, thpSize", thpSizeSize, "* 2 >= maxHeap", heapSize)
}
}
-func adjustAvailableMemory(measured int) int {
- reserved := 1024
- need_min := 64
- if measured > need_min+2*reserved {
- return measured - reserved
+func adjustAvailableMemory(measured AmountOfMemory) AmountOfMemory {
+ reserved := 1024 // MB
+ need_min := 64 // MB
+ available := measured.ToMB()
+ if available > need_min+2*reserved {
+ return MegaBytesOfMemory(available - reserved)
}
- if measured > need_min {
- return (measured + need_min) / 2
+ if available > need_min {
+ adjusted := (available + need_min) / 2
+ return MegaBytesOfMemory(adjusted)
}
- return need_min
+ return MegaBytesOfMemory(need_min)
}
diff --git a/client/go/jvm/mem_options_test.go b/client/go/jvm/mem_options_test.go
index 80ab588c8dc..d7bb05000ca 100644
--- a/client/go/jvm/mem_options_test.go
+++ b/client/go/jvm/mem_options_test.go
@@ -11,11 +11,12 @@ import (
func TestAdjustment(t *testing.T) {
lastAdj := 64
for i := 0; i < 4096; i++ {
- adj := adjustAvailableMemory(i)
- assert.True(t, adj >= lastAdj)
- lastAdj = adj
+ adj := adjustAvailableMemory(MegaBytesOfMemory(i)).ToMB()
+ assert.True(t, int(adj) >= lastAdj)
+ lastAdj = int(adj)
}
- assert.Equal(t, 30000, adjustAvailableMemory(31024))
+ adj := adjustAvailableMemory(MegaBytesOfMemory(31024)).ToMB()
+ assert.Equal(t, 30000, int(adj))
}
func TestParseFree(t *testing.T) {
@@ -24,11 +25,11 @@ func TestParseFree(t *testing.T) {
Mem: 19986 656 3157 218 16172 18832
Swap: 2047 320 1727
`)
- assert.Equal(t, 19986, res)
+ assert.Equal(t, MegaBytesOfMemory(19986), res)
}
func TestGetAvail(t *testing.T) {
trace.AdjustVerbosity(0)
- available := getAvailableMbOfMemory()
- assert.True(t, available >= 0)
+ available := getAvailableMemory()
+ assert.True(t, available.ToMB() >= 0)
}
diff --git a/client/go/jvm/options_test.go b/client/go/jvm/options_test.go
index c451b87ff24..99b6e8dd6f3 100644
--- a/client/go/jvm/options_test.go
+++ b/client/go/jvm/options_test.go
@@ -7,60 +7,69 @@ import (
"github.com/stretchr/testify/assert"
)
-const (
- aa = 123
- bb = 234
- cc = 456
- dd = 567
- ee = 16 * PowerOfTwo10
- ff = 31 * PowerOfTwo10
-)
-
-func TestHeapMbSimple(t *testing.T) {
+func TestHeapSizeSimple(t *testing.T) {
+ var (
+ aa = MegaBytesOfMemory(123)
+ bb = MegaBytesOfMemory(234)
+ )
o := NewOptions(NewStandaloneContainer("foo"))
- assert.Equal(t, aa, o.CurMinHeapMb(aa))
- assert.Equal(t, bb, o.CurMaxHeapMb(bb))
+ assert.Equal(t, aa, o.CurMinHeapSize(aa))
+ assert.Equal(t, bb, o.CurMaxHeapSize(bb))
assert.Equal(t, 2, len(o.jvmArgs))
assert.Equal(t, "-Xms123m", o.jvmArgs[0])
assert.Equal(t, "-Xmx234m", o.jvmArgs[1])
}
-func TestHeapMbMulti(t *testing.T) {
+func TestHeapSizeMulti(t *testing.T) {
+ var (
+ aa = MegaBytesOfMemory(123)
+ bb = MegaBytesOfMemory(234)
+ cc = MegaBytesOfMemory(456)
+ dd = MegaBytesOfMemory(567)
+ )
o := NewOptions(NewStandaloneContainer("foo"))
- assert.Equal(t, aa, o.CurMinHeapMb(aa))
- assert.Equal(t, aa, o.CurMaxHeapMb(aa))
+ assert.Equal(t, aa, o.CurMinHeapSize(aa))
+ assert.Equal(t, aa, o.CurMaxHeapSize(aa))
assert.Equal(t, 2, len(o.jvmArgs))
o.AppendOption("-Xms234m")
o.AppendOption("-Xmx456m")
assert.Equal(t, 4, len(o.jvmArgs))
- assert.Equal(t, bb, o.CurMinHeapMb(aa))
- assert.Equal(t, bb, o.CurMinHeapMb(dd))
- assert.Equal(t, cc, o.CurMaxHeapMb(aa))
- assert.Equal(t, cc, o.CurMaxHeapMb(dd))
+ assert.Equal(t, bb, o.CurMinHeapSize(aa))
+ assert.Equal(t, bb, o.CurMinHeapSize(dd))
+ assert.Equal(t, cc, o.CurMaxHeapSize(aa))
+ assert.Equal(t, cc, o.CurMaxHeapSize(dd))
o.AppendOption("-Xms1g")
o.AppendOption("-Xmx2g")
- assert.Equal(t, 1*PowerOfTwo10, o.CurMinHeapMb(aa))
- assert.Equal(t, 2*PowerOfTwo10, o.CurMaxHeapMb(aa))
+ assert.Equal(t, GigaBytesOfMemory(1), o.CurMinHeapSize(aa))
+ assert.Equal(t, GigaBytesOfMemory(2), o.CurMaxHeapSize(aa))
o.AppendOption("-Xms16777216k")
o.AppendOption("-Xmx32505856k")
- assert.Equal(t, ee, o.CurMinHeapMb(aa))
- assert.Equal(t, ff, o.CurMaxHeapMb(aa))
+ assert.Equal(t, KiloBytesOfMemory(16777216), o.CurMinHeapSize(aa))
+ assert.Equal(t, KiloBytesOfMemory(32505856), o.CurMaxHeapSize(aa))
}
-func TestHeapMbAdd(t *testing.T) {
+func TestHeapSizeAdd(t *testing.T) {
+ var (
+ gg = MegaBytesOfMemory(12345)
+ hh = MegaBytesOfMemory(23456)
+ )
o := NewOptions(NewStandaloneContainer("foo"))
- o.AddDefaultHeapSizeArgs(12345, 23456)
+ o.AddDefaultHeapSizeArgs(gg, hh)
assert.Equal(t, 3, len(o.jvmArgs))
assert.Equal(t, "-Xms12345m", o.jvmArgs[0])
assert.Equal(t, "-Xmx23456m", o.jvmArgs[1])
assert.Equal(t, "-XX:+UseTransparentHugePages", o.jvmArgs[2])
}
-func TestHeapMbNoAdd(t *testing.T) {
+func TestHeapSizeNoAdd(t *testing.T) {
+ var (
+ bb = MegaBytesOfMemory(234)
+ cc = MegaBytesOfMemory(456)
+ )
o := NewOptions(NewStandaloneContainer("foo"))
o.AppendOption("-Xms128k")
o.AppendOption("-Xmx1280k")
- o.AddDefaultHeapSizeArgs(234, 345)
+ o.AddDefaultHeapSizeArgs(bb, cc)
assert.Equal(t, 2, len(o.jvmArgs))
assert.Equal(t, "-Xms128k", o.jvmArgs[0])
assert.Equal(t, "-Xmx1280k", o.jvmArgs[1])