专栏/桌面窗口管理器(dwm.exe)占用内存高怎么办?

桌面窗口管理器(dwm.exe)占用内存高怎么办?

2021年07月29日 23:05--浏览 · --点赞 · --评论
粉丝:464文章:3


心肺骤停

文章结尾有下载链接!


下面是我的解决方案

我不打算折腾驱动,所以我选择了比较暴力通用的方法

既然桌面窗口管理器(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


投诉或建议