2019-05-22 23:16:55 +02:00
package memory
import (
"flag"
"fmt"
"sync"
2020-08-16 16:05:52 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
2019-05-22 23:16:55 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
)
2020-08-14 18:12:10 +02:00
var (
allowedPercent = flag . Float64 ( "memory.allowedPercent" , 60 , "Allowed percent of system memory VictoriaMetrics caches may occupy. " +
"See also -memory.allowedBytes. " +
"Too low value may increase cache miss rate, which usually results in higher CPU and disk IO usage. " +
"Too high value may evict too much data from OS page cache, which will result in higher disk IO usage" )
2020-08-16 16:05:52 +02:00
allowedBytes = flagutil . NewBytes ( "memory.allowedBytes" , 0 , "Allowed size of system memory VictoriaMetrics caches may occupy. " +
2020-08-14 18:12:10 +02:00
"This option overrides -memory.allowedPercent if set to non-zero value. " +
"Too low value may increase cache miss rate, which usually results in higher CPU and disk IO usage. " +
"Too high value may evict too much data from OS page cache, which will result in higher disk IO usage" )
)
2019-05-22 23:16:55 +02:00
2019-08-25 13:39:39 +02:00
var (
allowedMemory int
remainingMemory int
)
2019-05-22 23:16:55 +02:00
var once sync . Once
2019-08-25 13:39:39 +02:00
func initOnce ( ) {
if ! flag . Parsed ( ) {
// Do not use logger.Panicf here, since logger may be uninitialized yet.
panic ( fmt . Errorf ( "BUG: memory.Allowed must be called only after flag.Parse call" ) )
}
mem := sysTotalMemory ( )
2020-08-16 16:05:52 +02:00
if allowedBytes . N <= 0 {
2020-08-14 18:12:10 +02:00
if * allowedPercent < 1 || * allowedPercent > 200 {
2020-10-20 11:38:46 +02:00
logger . Panicf ( "FATAL: -memory.allowedPercent must be in the range [1...200]; got %g" , * allowedPercent )
2020-08-14 18:12:10 +02:00
}
percent := * allowedPercent / 100
allowedMemory = int ( float64 ( mem ) * percent )
2020-08-16 15:04:11 +02:00
remainingMemory = mem - allowedMemory
2020-10-20 11:38:46 +02:00
logger . Infof ( "limiting caches to %d bytes, leaving %d bytes to the OS according to -memory.allowedPercent=%g" , allowedMemory , remainingMemory , * allowedPercent )
2020-08-14 18:12:10 +02:00
} else {
2020-08-16 16:05:52 +02:00
allowedMemory = allowedBytes . N
2020-08-16 15:04:11 +02:00
remainingMemory = mem - allowedMemory
2020-08-16 16:05:52 +02:00
logger . Infof ( "limiting caches to %d bytes, leaving %d bytes to the OS according to -memory.allowedBytes=%s" , allowedMemory , remainingMemory , allowedBytes . String ( ) )
2020-08-14 18:12:10 +02:00
}
2019-08-25 13:39:39 +02:00
}
2019-05-22 23:16:55 +02:00
// Allowed returns the amount of system memory allowed to use by the app.
//
// The function must be called only after flag.Parse is called.
func Allowed ( ) int {
2019-08-25 13:39:39 +02:00
once . Do ( initOnce )
2019-05-22 23:16:55 +02:00
return allowedMemory
}
2019-08-25 13:39:39 +02:00
// Remaining returns the amount of memory remaining to the OS.
//
// This function must be called only after flag.Parse is called.
func Remaining ( ) int {
once . Do ( initOnce )
return remainingMemory
}