oom-killer: Free memory on pressure notification and use gradual interval backoff

This commit is contained in:
世界
2026-04-07 21:19:40 +08:00
parent 4806d5e588
commit 0d772e6893
2 changed files with 18 additions and 7 deletions

View File

@@ -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)

View File

@@ -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,7 +179,9 @@ func (t *adaptiveTimer) poll() {
t.state = t.nextState(sample)
if t.state == pressureStateNormal {
t.forceMinInterval = false
t.pressureBaselineTime = time.Time{}
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
@@ -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 {