mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-11 17:47:20 +10:00
oom-killer: Free memory on pressure notification and use gradual interval backoff
This commit is contained in:
@@ -33,6 +33,7 @@ static void stopMemoryPressureMonitor() {
|
||||
import "C"
|
||||
|
||||
import (
|
||||
runtimeDebug "runtime/debug"
|
||||
"sync"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
@@ -88,6 +89,7 @@ func (s *Service) Close() error {
|
||||
|
||||
//export goMemoryPressureCallback
|
||||
func goMemoryPressureCallback(status C.ulong) {
|
||||
runtimeDebug.FreeOSMemory()
|
||||
globalAccess.Lock()
|
||||
services := make([]*Service, len(globalServices))
|
||||
copy(services, globalServices)
|
||||
|
||||
@@ -107,6 +107,7 @@ type adaptiveTimer struct {
|
||||
access sync.Mutex
|
||||
timer *time.Timer
|
||||
state pressureState
|
||||
currentInterval time.Duration
|
||||
forceMinInterval bool
|
||||
pendingPressureBaseline bool
|
||||
pressureBaseline memorySample
|
||||
@@ -178,8 +179,10 @@ func (t *adaptiveTimer) poll() {
|
||||
t.state = t.nextState(sample)
|
||||
if t.state == pressureStateNormal {
|
||||
t.forceMinInterval = false
|
||||
if !t.pressureBaselineTime.IsZero() && time.Since(t.pressureBaselineTime) > t.maxInterval {
|
||||
t.pressureBaselineTime = time.Time{}
|
||||
}
|
||||
}
|
||||
t.timer.Reset(t.intervalForState())
|
||||
triggered = previousState != pressureStateTriggered && t.state == pressureStateTriggered
|
||||
if !triggered && !t.pressureBaselineTime.IsZero() && t.memoryLimit > 0 &&
|
||||
@@ -272,13 +275,19 @@ func (t *adaptiveTimer) availableThresholds(sample memorySample) pressureThresho
|
||||
}
|
||||
|
||||
func (t *adaptiveTimer) intervalForState() time.Duration {
|
||||
if t.state == pressureStateNormal {
|
||||
return t.maxInterval
|
||||
switch {
|
||||
case t.forceMinInterval || t.state == pressureStateTriggered:
|
||||
t.currentInterval = t.minInterval
|
||||
case t.state == pressureStateArmed:
|
||||
t.currentInterval = t.armedInterval
|
||||
default:
|
||||
if t.currentInterval == 0 {
|
||||
t.currentInterval = t.maxInterval
|
||||
} else {
|
||||
t.currentInterval = min(t.currentInterval*2, t.maxInterval)
|
||||
}
|
||||
if t.forceMinInterval || t.state == pressureStateTriggered {
|
||||
return t.minInterval
|
||||
}
|
||||
return t.armedInterval
|
||||
return t.currentInterval
|
||||
}
|
||||
|
||||
func (t *adaptiveTimer) logDetails(sample memorySample) string {
|
||||
|
||||
Reference in New Issue
Block a user