using Ayay.SerilogLogs; using Serilog; using System.Diagnostics; using System.Timers; namespace SHH.MjpegPlayer; /// /// 内存监控 /// public static class MemoryWatchdog { private static readonly ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); private static System.Timers.Timer? _timer; private static long _thresholdBytes; private static ILogger _logger => Log.Logger; /// /// 启动内存监控 /// /// 检查间隔(秒),默认60秒 /// 内存阈值(MB),超过此值自动退出,默认800MB public static void Start(int intervalSeconds = 60, int limitMB = 800) { // 1. 参数安全检查 if (intervalSeconds < 1) intervalSeconds = 1; // 至少 1 秒 if (limitMB < 100) limitMB = 100; // 至少100MB,防止误杀 // 2. 转换单位 // MB -> Bytes _thresholdBytes = (long)limitMB * 1024 * 1024; // 秒 -> 毫秒 double intervalMs = intervalSeconds * 1000.0; // 3. 初始化定时器 Stop(); // 防止重复启动 _timer = new System.Timers.Timer(intervalMs); _timer.Elapsed += CheckMemoryUsage; _timer.AutoReset = true; // 循环执行 _timer.Start(); // 可选:记录启动日志 if (_logger != null) { _sysLog.Warning($"[系统] 内存看门狗已启动。每 {intervalSeconds} 秒检查一次,阈值: {limitMB} MB."); } } private static void CheckMemoryUsage(object sender, ElapsedEventArgs e) { try { Process currentProc = Process.GetCurrentProcess(); // 【重要】刷新快照 currentProc.Refresh(); long currentUsage = currentProc.WorkingSet64; if (currentUsage > _thresholdBytes) { double currentMB = currentUsage / 1024.0 / 1024.0; double limitMB = _thresholdBytes / 1024.0 / 1024.0; if (_logger != null) { _sysLog.Warning($"[严重] 内存占用 ({currentMB:F2} MB) 超过阈值 ({limitMB} MB),程序即将自杀重启或退出."); } // 等待日志输出 for (var i = 0; i < 10; i++) { System.Threading.Thread.Sleep(100); } // 强制退出 Environment.Exit(0); } } catch (Exception ex) { if (_logger != null) { _sysLog.Warning($"[严重] 内存检查出错."); } } } public static void Stop() { if (_timer != null) { _timer.Stop(); _timer.Dispose(); _timer = null; } } }