Record memory usage continuously in OOM report

This commit is contained in:
世界
2026-09-02 20:01:03 +08:00
parent 0944cd9d7b
commit 21b8fcacc6
22 changed files with 1277 additions and 333 deletions
+35 -7
View File
@@ -102,7 +102,8 @@ type adaptiveTimer struct {
timerConfig
logger log.ContextLogger
network adapter.NetworkManager
onTriggered func(uint64)
connections adapter.ConnectionManager
recorder *Recorder
limitThresholds pressureThresholds
access sync.Mutex
@@ -115,12 +116,13 @@ type adaptiveTimer struct {
pressureBaselineTime time.Time
}
func newAdaptiveTimer(logger log.ContextLogger, network adapter.NetworkManager, config timerConfig, onTriggered func(uint64)) *adaptiveTimer {
func newAdaptiveTimer(logger log.ContextLogger, network adapter.NetworkManager, connections adapter.ConnectionManager, recorder *Recorder, config timerConfig) *adaptiveTimer {
t := &adaptiveTimer{
timerConfig: config,
logger: logger,
network: network,
onTriggered: onTriggered,
connections: connections,
recorder: recorder,
}
if config.policyMode == policyModeMemoryLimit || config.policyMode == policyModeNetworkExtension {
t.limitThresholds = computeLimitThresholds(config.memoryLimit, config.safetyMargin)
@@ -192,14 +194,24 @@ func (t *adaptiveTimer) poll() {
}
}
}
state := t.state
t.access.Unlock()
var connections int
if t.connections != nil {
connections = t.connections.Count()
}
if t.recorder != nil {
t.recorder.sample(sample, state, connections)
if state != previousState {
t.recorder.recordStateChange(state, sample)
}
}
if !triggered {
return
}
if t.onTriggered != nil {
t.onTriggered(sample.usage)
}
var reason string
if rateTriggered {
reason = resetReasonRate
if t.killerDisabled {
t.logger.Warn("memory growth rate critical (report only), usage: ", byteformats.FormatMemoryBytes(sample.usage), t.logDetails(sample))
} else {
@@ -207,6 +219,7 @@ func (t *adaptiveTimer) poll() {
t.network.ResetNetwork(context.Background())
}
} else {
reason = resetReasonThreshold
if t.killerDisabled {
t.logger.Warn("memory threshold reached (report only), usage: ", byteformats.FormatMemoryBytes(sample.usage), t.logDetails(sample))
} else {
@@ -216,6 +229,10 @@ func (t *adaptiveTimer) poll() {
}
badCleanup()
runtimeDebug.FreeOSMemory()
if t.recorder != nil {
t.recorder.recordReset(reason, sample, readMemorySample(t.policyMode), connections, t.killerDisabled)
t.recorder.snapshot(SnapshotReasonReset, sample, false)
}
}
func (t *adaptiveTimer) nextState(sample memorySample) pressureState {
@@ -320,9 +337,20 @@ func readMemorySample(mode policyMode) memorySample {
sample := memorySample{
usage: memory.Total(),
}
if mode == policyModeAvailable {
if mode == policyModeAvailable || mode == policyModeNetworkExtension {
sample.availableKnown = true
sample.available = memory.Available()
}
return sample
}
func (s pressureState) String() string {
switch s {
case pressureStateArmed:
return "armed"
case pressureStateTriggered:
return "triggered"
default:
return "normal"
}
}