
文章结尾有下载链接!
下面是我的解决方案
我不打算折腾驱动,所以我选择了比较暴力通用的方法
既然桌面窗口管理器(dwm.exe)内存泄漏占用大量内存,那么我只要监测dwm.exe占用了多少内存,只要占用的内存高于正常值,就直接重启dwm.exe即可。暴力GC
使用方法:
数字键选择功能

第一次使用建议先安装(1.Install)然后再启动(3.Start)
如需卸载请先终止(4.Stop)然后再卸载(2.Uninstall)
退出请按5(5.Exit)
下面是代码实现
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration.Install;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;
namespace DWMMemoryLeakFix
{
class Program
{
static string ServiceFilePath { get; set; }
static string ServiceName { get; set; }
private static bool IsServiceExisted(string serviceName)
{
ServiceController[] services = ServiceController.GetServices();
foreach (ServiceController sc in services)
{
if (sc.ServiceName.ToLower() == serviceName.ToLower())
{
return true;
}
}
return false;
}
public static ServiceControllerStatus GetServiceStatus(string serviceName)
{
ServiceController service = new ServiceController(serviceName);
return service.Status;
}
public static void UninstallService(string serviceName)
{
TransactedInstaller ti = new TransactedInstaller();
ti.Installers.Add(new ServiceInstaller
{
ServiceName = serviceName
});
ti.Uninstall(null);
}
public static void InstallService(string serviceFilePath, string serviceName, ServiceStartMode startType, string[] servicesDependedOn = null, string description = null)
{
TransactedInstaller ti = new TransactedInstaller
{
Context = new InstallContext()
};
ti.Context.Parameters["assemblypath"] = serviceFilePath;
ti.Installers.Add(new ServiceProcessInstaller
{
Account = ServiceAccount.LocalSystem
});
ti.Installers.Add(new ServiceInstaller
{
DisplayName = serviceName,
ServiceName = serviceName,
StartType = startType,
Description = description,
ServicesDependedOn = servicesDependedOn
});
ti.Install(new Hashtable());
}
private static void ServiceStart(string serviceName)
{
using (ServiceController control = new ServiceController(serviceName))
{
if (control.Status == ServiceControllerStatus.Stopped)
{
control.Start();
}
}
}
private static void ServiceStop(string serviceName)
{
using (ServiceController control = new ServiceController(serviceName))
{
if (control.Status == ServiceControllerStatus.Running)
{
control.Stop();
}
}
}
static void Main(string[] args)
{
List<string> StartupParameters = args.ToList();
ServiceFilePath = $"\"{Process.GetCurrentProcess().MainModule.FileName}\" service";
ServiceName = Assembly.GetExecutingAssembly().FullName.Substring(0, Assembly.GetExecutingAssembly().FullName.IndexOf(","));
if (StartupParameters.Count < 1)
{
while (true)
{
try
{
Console.WriteLine("1.Install\r\n2.Uninstall\r\n3.Start\r\n4.Stop\r\n5.Exit");
Console.Write("Enter:");
switch (Console.ReadKey().Key)
{
case ConsoleKey.NumPad1:
case ConsoleKey.D1:
Console.Clear();
if (IsServiceExisted(ServiceName)) UninstallService(ServiceName);
InstallService(ServiceFilePath, ServiceName, ServiceStartMode.Automatic);
Console.WriteLine("Install Complete.");
continue;
case ConsoleKey.NumPad2:
case ConsoleKey.D2:
Console.Clear();
if (IsServiceExisted(ServiceName))
{
ServiceStop(ServiceName);
UninstallService(ServiceName);
}
Console.WriteLine("Uninstall Complete.");
continue;
case ConsoleKey.NumPad3:
case ConsoleKey.D3:
Console.Clear();
if (IsServiceExisted(ServiceName)) ServiceStart(ServiceName);
Console.WriteLine("Start Complete.");
continue;
case ConsoleKey.NumPad4:
case ConsoleKey.D4:
Console.Clear();
if (IsServiceExisted(ServiceName)) ServiceStop(ServiceName);
Console.WriteLine("Stop Complete.");
continue;
case ConsoleKey.NumPad5:
case ConsoleKey.D5:
return;
default:
Console.Clear();
continue;
}
}
catch (Exception)
{
continue;
}
}
}
else
{
if (StartupParameters[0].ToLower() == "service")
{
try
{
ServiceBase[] serviceToRun = new ServiceBase[] { new DWMMemoryLeakFixService() };
ServiceBase.Run(serviceToRun);
}
catch (Exception ex)
{
EventLog.WriteEntry(ServiceName, ex.ToString(), EventLogEntryType.Error);
}
}
}
}
}
partial class DWMMemoryLeakFixService : ServiceBase
{
public Task WorkTask { get; set; }
public CancellationTokenSource TaskTokenSource { get; set; }
public DWMMemoryLeakFixService()
{
ServiceName = Assembly.GetExecutingAssembly().FullName.Substring(0, Assembly.GetExecutingAssembly().FullName.IndexOf(","));
TaskTokenSource = new CancellationTokenSource();
}
public static string GetFileLengthInfo(long Length)
{
long mod = 1024;
int order = 0;
while (Length >= mod)
{
Length /= mod;
order++;
}
return string.Format("{0:0.##} {1}", Length, new string[] { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", "BB", "NB", "DB", "CB", "XB" }[order]);
}
protected override void OnStart(string[] args)
{
EventLog.WriteEntry(ServiceName, "DWM MemoryLeak Monitoring...", EventLogEntryType.Information);
WorkTask = Task.Factory.StartNew(() => {
Debugger.Break();
while (true)
{
try
{
TaskTokenSource.Token.ThrowIfCancellationRequested();
foreach (var item in Process.GetProcessesByName("dwm"))
{
if ((item.PrivateMemorySize64 / 1048576) > 512)
{
EventLog.WriteEntry(ServiceName, "DWM Private Memory Size " + GetFileLengthInfo(item.PrivateMemorySize64), EventLogEntryType.Information);
string dwm = item.MainModule.FileName.ToString();
item.Kill();
Process.Start(dwm);
}
}
Thread.Sleep(1000 * 30);
TaskTokenSource.Token.ThrowIfCancellationRequested();
}
catch (OperationCanceledException)
{
return;
}
catch (Exception ex)
{
EventLog.WriteEntry(ServiceName, ex.ToString(), EventLogEntryType.Error);
}
}
}, TaskTokenSource.Token);
return;
}
protected override void OnStop()
{
TaskTokenSource.Cancel();
WorkTask.Wait();
EventLog.WriteEntry(ServiceName, "DWM MemoryLeak Monitor Stop", EventLogEntryType.Information);
return;
}
}
}
求硬币 求收藏 求点赞[以下内容三联可见(雾]

欢迎转载,但是请附上本文链接在转载文章的醒目位置!
禁止二次分发,防止出现致命问题之后无法更新
下载地址:
https://alywp.net/21JvsI
下载工具文件夹下的DWMMemoryLeakFix.exe