@ -4,6 +4,8 @@ package mem
import (
"context"
"math"
"os"
"strconv"
"strings"
@ -103,8 +105,9 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
ret . Cached += ret . SReclaimable
if ! memavail {
ret . Available = ret . Free + ret . Buffers + ret . Cached
ret . Available = calcuateAvailVmem ( ret )
}
ret . Used = ret . Total - ret . Free - ret . Buffers - ret . Cached
ret . UsedPercent = float64 ( ret . Used ) / float64 ( ret . Total ) * 100.0
@ -156,3 +159,39 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
}
return ret , nil
}
func calcuateAvailVmem ( ret * VirtualMemoryStat ) uint64 {
var watermarkLow uint64
fn := common . HostProc ( "zoneinfo" )
lines , _ := common . ReadLines ( fn )
pagesize := uint64 ( os . Getpagesize ( ) )
watermarkLow = 0
for _ , line := range lines {
fields := strings . Fields ( line )
if strings . HasPrefix ( fields [ 0 ] , "low" ) {
lowValue , err := strconv . ParseUint ( fields [ 1 ] , 10 , 64 )
if err != nil {
lowValue = 0
}
watermarkLow += lowValue
}
}
watermarkLow *= pagesize
availMemory := ret . Free - watermarkLow
pageCache := ret . Active + ret . Inactive
pageCache -= uint64 ( math . Min ( float64 ( pageCache / 2 ) , float64 ( watermarkLow ) ) )
availMemory += pageCache
availMemory += ret . SReclaimable - uint64 ( math . Min ( float64 ( ret . SReclaimable / 2.0 ) , float64 ( watermarkLow ) ) )
if availMemory < 0 {
availMemory = 0
}
return availMemory
}