内存清理加速器 (MemoryBooster)

一款 Windows 桌面内存清理与进程管理工具,UI 风格参考 360 安全卫士加速球。平时悬浮球隐藏在屏幕右侧,鼠标靠近自动滑出,左键一键清理内存,右键打开管理面板。

本文档面向使用者与二次开发者,介绍项目实现算法原理、环境要求、安装步骤、运行步骤、注意事项以及文件夹结构。


效果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、项目实现算法原理

项目采用 C# WPF 前端 + C++ DLL 后端 的双层架构。所有 Windows API 调用集中在 MemoryCore.cpp 中,C# 侧通过 P/Invoke 调用,结构体使用 pack=1 对齐保证两侧内存布局一致。

1.1 内存清理算法(核心)

内存清理的底层原理是 释放进程工作集(Working Set)回操作系统。工作集是进程当前驻留在物理内存中的页面集合;当调用 EmptyWorkingSet 时,这些页面被换出到 pagefile,物理内存(可用内存)随之上升。被换出的页面在进程再次访问时会通过缺页中断按需调回,因此清理是「释放」而非「删除」内存。

  • 一键清理 CleanAllWorkingSets:通过 CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS) 枚举系统所有进程,对每个 PID 调用 OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_QUOTA) 后执行 EmptyWorkingSet,统计成功清理的进程数。
  • 单进程清理 CleanProcessWorkingSet:对指定 PID 直接执行上述流程。
  • 清理释放量统计:C# 业务层在清理前后各调用一次 GetSystemMemoryInfo(底层 GlobalMemoryStatusEx),取 ullAvailPhys 差值即为释放字节数。
  • 自身瘦身:C# 侧通过 SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1) 直接对本进程工作集进行 trim,每 60 秒由定时器执行一次,保持加速器自身占用最小。

1.2 进程信息采集算法

  • 进程枚举CreateToolhelp32Snapshot + Process32FirstW / Process32NextW 遍历系统进程。
  • 内存信息GetProcessMemoryInfoWorkingSetSize(工作集大小)与 PrivateUsage(私有字节)。
  • 可执行文件路径QueryFullProcessImageNameW 获取进程映像完整路径。
  • 受保护进程兼容OpenProcess 失败时降级用 PROCESS_QUERY_LIMITED_INFORMATION 重试,使受保护进程(如系统服务)仍能取到部分信息。
  • 前台进程识别:C# 侧通过 EnumWindows 枚举所有顶层窗口,过滤条件为「可见 + 无 Owner + 标题非空」,再通过 GetWindowThreadProcessId 反查 PID,得到 PID → 主窗口标题的映射,从而区分前台应用与后台进程。
  • 排序:按工作集大小降序排序。

1.3 CPU 占用率采样算法

CPU% 不能简单取瞬时值,需要 两次采样差值除以时间间隔 才有意义:

  1. 调用 GetProcessTimes 获取进程的 KernelTimeUserTime(FILETIME,单位 100 ns)。
  2. 两者相加得到总 tick 数,存入全局 g_cpuMap[pid] = { ticks, sampleMs }
  3. 下次采样时计算 deltaTicks / 10'000'000.0 秒,再除以 elapsedSec × CPU 核数,归一化到 0–100%。
  4. 每个 PID 维护独立的 lastSampleTime,避免新出现进程首次读数被放大、长时间间隔后读数被过度放大,行为与任务管理器一致。
  5. 每轮采集结束后用本次见过的 PID 集合 swap 替换旧表,让已退出进程条目自动淘汰,避免 map 无限增长。

1.4 系统内存占用百分比

直接调用 GlobalMemoryStatusEx,读取 MEMORYSTATUSEX.dwMemoryLoad(操作系统给出的物理内存占用百分比)。悬浮球颜色按阈值切换:<50% 绿 → 50–80% 黄橙 → >80% 红。

1.5 网速监控算法

系统级总速率 GetNetTotalStats
  1. 调用 GetIfTable2 枚举所有网卡,仅累加 物理网卡(以太网 / Wi-Fi / WMAN / WWAN),跳过 loopback 与 tunnel / 虚拟网卡(WSL / Hyper-V / VMware / VPN),避免虚拟交换机镜像物理网卡字节导致的重复计数。
  2. 维护全局 { lastSampleMs, lastIn, lastOut },本次累计值与上次差除以时间间隔得到 bytes/s。
  3. 时间间隔小于 50 ms 时按 50 ms 计,避免除零或异常放大。
进程级 TCP 速率 GetPerProcessNetStats(需管理员权限)

通过 TCP ESTATS(Extended Statistics)API 实现按进程的字节级速率统计:

  1. GetExtendedTcpTable 枚举所有 TCP 连接(v4 + v6),每条连接由四元组(本地/远端 地址 + 端口)唯一标识。
  2. 维护全局 g_v4Conns / g_v6Conns 两个 map,键为四元组,值为 ConnState { pid, prevIn, prevOut, lastSeenMs }
  3. 新连接出现时调用 SetPerTcpConnectionEStats 启用 ESTATS 数据采集,读一次基准 DataBytesIn / DataBytesOut
  4. 已存在连接每次调用 GetPerTcpConnectionEStats 读累计字节,与上次值做差累加到对应 PID 的聚合表。
  5. 无管理员权限时 ESTATS 启用失败,仍统计 TCP / UDP 连接数但跳过字节速率。
  6. 超过 10 秒未见的连接从 map 中过期清除,防止表无限增长。
  7. UDP 连接计数通过 GetExtendedUdpTable 完成(仅计数,无字节级统计)。

1.6 单实例运行算法

启动时创建命名 Mutex Local\MemoryBooster.SingleInstance.{固定GUID}

  • createdNew == true → 本实例为首发,继续启动;退出时 ReleaseMutex + Dispose
  • createdNew == false → 已有实例运行,弹窗提示后立即 Shutdown

Local\ 前缀限定当前用户会话,避免跨用户冲突;GUID 后缀避免与同名产品混淆。

1.7 设置持久化算法

使用 XmlSerializerAppSettings 序列化为 XML,存于 %APPDATA%\MemoryBooster\settings.xmlSave / Load 全程 try-catch,出错时静默降级为默认值,永不抛异常打断用户操作。

1.8 开机自启算法

向注册表 HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run 写入 / 删除键值 MemoryBooster = "exe 路径" 实现(HKCU 不需要管理员权限)。

1.9 悬浮球交互算法

  • 窗口属性:WindowStyle=None, AllowsTransparency=True, Topmost=True, ShowInTaskbar=False,常驻最前但不进任务栏。
  • 滑出 / 隐藏:鼠标靠近时 200ms 动画从屏幕右侧滑出;离开后 800ms 延迟再滑回仅露 14px。
  • 左键:一键清理内存(带旋转动画);若管理面板已开则关闭面板。
  • 左键拖拽:上下拖动调整位置,Y 坐标自动写入设置。
  • 右键:打开 / 关闭管理面板。

1.10 异常处理算法

App.xaml.cs 挂接三处全局异常钩子:

  • DispatcherUnhandledException(UI 线程)→ 记日志并 e.Handled = true 阻止崩溃
  • AppDomain.UnhandledException(非 UI 线程致命异常)→ 记日志
  • TaskScheduler.UnobservedTaskException(未观察的 Task 异常)→ 记日志并 SetObserved

日志懒加载EnsureLogPath() 仅在真正出错时才探测并创建 error.log,正常运行不产生空文件;写入路径优先 exe 同目录,失败回退 %LocalAppData%\MemoryBooster\error.log。所有定时器 Tick 回调均用 try-catch 包裹。

1.11 DataGrid 虚拟化兼容算法

WPF DataGrid 在启用容器虚拟化时存在两个已知崩溃点,项目用以下方式规避:

  • 分组:以 IsSectionBreak 字段 + DataTrigger 画分割线 取代 GroupStyle,避免虚拟化 + 分组 + 快速滚动的 NRE 崩溃。
  • 路径显示:放弃 Binding Tag, RelativeSource={RelativeSource AncestorType=Window}(容器回收瞬间 parent 为 null 会触发 PropertyMetadata.get_DefaultValue() NRE),改为给 ProcessInfo 增加 PathVisibility 属性并实现 INotifyPropertyChanged,DataTemplate 直接绑 DataContext。

1.12 进程列表滚动 / 选中持久化算法

刷新进程快照时按 PID 记住视口首行与当前选中项,新快照就位后用 ScrollIntoView 回滚并恢复 SelectedItem,避免新增前台进程把用户视线挤走;右键菜单弹出前通过 ContextMenuOpeningSelectedItem 拨回当前红色选中项,确保菜单始终针对当前选中进程操作。


二、环境要求

2.1 运行环境(最终用户)

项目 要求
操作系统 Windows 7 SP1 及以上(64 位)
.NET Framework 4.5 / 4.6 / 4.7 / 4.8 任一版本
系统位数 64 位(MemoryCore.dll 为 x64 编译)
权限 普通用户可运行;清理其他进程内存 / 进程级网速统计需管理员权限

选择 net45 的原因:4.5 是支持 async/await + Task.Run + Dispatcher.InvokeAsync 的最低 4.x 版本,Win7 SP1 及以上系统通过 Windows Update 都装有 4.5+ 运行时;目标设为 4.5 意味着 4.5/4.6/4.7/4.8 任意版本都能跑,兼容面最大。

2.2 开发环境(二次开发)

工具 版本
Visual Studio 2022(含 C# 桌面开发 + C++ 桌面开发工作负载)
.NET SDK 任意支持 net45 引用程序集的版本
CMake 3.20 及以上
C++ 编译器 MSVC(支持 C++17)
Windows SDK 含 psapi / iphlpapi / ws2_32 / tcpestats 头文件

三、安装步骤

3.1 直接使用预编译产物(推荐)

仓库已附带预编译产物,无需构建:

  1. 解压根目录压缩包 内存清理加速球2.0.zip,或将 MemoryBooster/bin/Release/net45/ 下两个文件拷贝到任意可写目录:
    • 内存清理加速器.exe
    • MemoryCore.dll
  2. 两个文件 必须放在同一目录,否则 P/Invoke 会因找不到 DLL 而抛 DllNotFoundException
  3. 双击 内存清理加速器.exe 即可运行。

3.2 从源码构建

3.2.1 构建 C++ DLL
cd MemoryCore
mkdir build
cd build
cmake .. -G "Visual Studio 17 2022" -A x64
cmake --build . --config Release

产物位于 MemoryCore/build/bin/Release/MemoryCore.dll(x64)。CMakeLists.txt 中已设置 _WIN32_WINNT=0x0601,确保 MIB_IF_ROW2 与 ESTATS API 在 SDK 头文件中被声明。

3.2.2 构建 C# WPF 主程序
cd MemoryBooster
dotnet build --configuration Release

csproj 中已配置 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>,会把仓库根的 MemoryCore.dll 副本自动拷贝到输出目录 bin/Release/net45/

3.2.3 手动同步 DLL(如需要)
copy MemoryCore\build\bin\Release\MemoryCore.dll MemoryBooster\bin\Release\net45\

四、运行步骤

  1. 启动:双击 内存清理加速器.exe。首次启动会在屏幕右侧出现悬浮加速球(仅露出 14px)。
  2. 唤出加速球:将鼠标移至屏幕右边缘附近,加速球自动滑出。
  3. 一键清理:左键单击加速球,触发全量工作集清理,清理完成后弹出气泡显示「清理进程数 / 释放字节数」。
  4. 打开管理面板:右键单击加速球,打开管理面板,包含三个 Tab:
    • ⚡ 加速:内存占用百分比 + 一键加速按钮 + 进程列表(名称 / 内存 / CPU / 复选框)+ 搜索 + 排序下拉 + 显示路径 / 显示前台窗口进程复选框 + 清理 / 结束进程按钮 + 右键菜单(结束进程 / 打开文件位置 / 复制路径)。
    • ⇅ 网速:上传 / 下载实时速度 + 累计流量(可通过启用开关关闭整个网络监控节省资源)。
    • ⚙ 设置:开机自启、自动清理、清理间隔、网络监视开关、透明度、皮肤切换、关于信息、退出按钮。
  5. 拖拽定位:左键按住加速球可上下拖动,Y 坐标自动保存到设置;下次启动恢复。
  6. 退出:右键面板「设置」Tab → 退出按钮(如开启了「最小化到托盘」则会先弹确认对话框)。

4.1 运行时生成文件

文件 路径 说明
settings.xml %APPDATA%\MemoryBooster\settings.xml 用户设置
error.log exe 同目录(可写时)或 %LocalAppData%\MemoryBooster\error.log 异常日志(仅首次异常时才创建

五、注意事项

  1. DLL 与 EXE 必须同目录MemoryCore.dll 是 P/Invoke 依赖,缺失会抛 DllNotFoundException
  2. 必须 64 位系统MemoryCore.dll 为 x64 编译,无法在 32 位系统加载。
  3. 权限要求
    • 普通用户权限下,仅能清理自身进程工作集;其他进程因 OpenProcess 被拒而跳过。
    • 清理全部进程内存、查看进程级 TCP 网速需要 SeDebugPrivilege 与管理员权限。
  4. DLL 导出名称MemoryCore.h 中所有函数必须在 extern "C" 块内,避免 C++ 名称修饰导致 C# 找不到入口点。可用 dumpbin /exports MemoryCore.dll 验证导出符号。
  5. 结构体对齐:C++ 与 C# 两侧必须都用 pack=1,否则字段偏移不一致导致数据错乱。
  6. .NET Framework 4.5 兼容性限制
    • net45 原生无 ValueTuple → 项目已通过 System.ValueTuple 4.5.0 NuGet 包 backport。
    • 不能使用 nullable reference typesstring?)。
    • 不能使用 Environment.ProcessPath(用 Assembly.GetExecutingAssembly().Location)。
    • LangVersion=latest 下 file-scoped namespace / record 等纯 C# 语法糖仍可用。
  7. 单实例:多开会被 Mutex 拦截并弹窗退出;若进程异常残留 Mutex,重启系统或 taskkill /f /im 内存清理加速器.exe 即可恢复。
  8. 网速统计准确性:系统级总速率仅聚合物理网卡,已自动排除 WSL / Hyper-V / VMware / VPN 等虚拟网卡的重复计数;进程级速率依赖 TCP ESTATS,必须以管理员身份运行,否则只能显示连接数无法显示字节速率。
  9. DataGrid 兼容性:WPF DataGrid 虚拟化 + GroupStyle 在快速滚动时存在已知 NRE 崩溃,本项目用 IsSectionBreak 字段 + DataTrigger 画分割线替代分组;路径列绑定 ProcessInfo.PathVisibility 而非 RelativeSource AncestorType=Window,避免容器回收瞬间触发 NRE。修改进程列表 UI 时务必保持这两处约定。
  10. 日志懒加载:正常运行不会产生 error.log,仅在首次异常时才创建;不要在启动阶段主动调用 EnsureLogPath()

六、文件夹结构介绍

jiasuqiu/
├── MemoryCore/                          # C++ 后端 DLL 项目
│   ├── CMakeLists.txt                   # CMake 构建配置(C++17 / _WIN32_WINNT=0x0601)
│   ├── MemoryCore.h                     # 导出函数声明 + 结构体定义(pack=1)
│   └── MemoryCore.cpp                   # Win32 API 实现(内存清理 / 进程枚举 / 网速采样 / ESTATS)
│
├── MemoryBooster/                       # C# WPF 前端项目
│   ├── MemoryBooster.csproj             # 项目文件:net45 + AssemblyName=内存清理加速器 + ValueTuple backport
│   ├── App.xaml / App.xaml.cs           # 应用入口:单实例 Mutex + 全局异常处理 + 懒加载日志
│   ├── MainWindow.xaml / MainWindow.xaml.cs   # 悬浮加速球窗口(滑出 / 隐藏 / 拖拽 / 一键清理)
│   ├── AssemblyInfo.cs                  # 程序集信息
│   ├── App.config                        # 应用配置
│   ├── app.manifest                     # UAC 清单
│   ├── MemoryCore.dll                   # DLL 副本(构建时复制到输出目录)
│   ├── Assets/
│   │   └── icon.ico                     # 应用图标
│   ├── Models/
│   │   ├── AppSettings.cs               # 设置模型 + XML 持久化(%APPDATA%\MemoryBooster\settings.xml)
│   │   └── ProcessInfo.cs               # 进程数据模型(含 PathVisibility / IsSectionBreak)
│   ├── Services/
│   │   ├── NativeInterop.cs             # P/Invoke 声明 + 结构体映射(Cdecl / pack=1)
│   │   ├── MemoryService.cs             # 内存 / 进程业务逻辑 + 前台窗口枚举 + 强力结束进程回退
│   │   ├── NetworkMonitor.cs            # 系统级网速计算与格式化
│   │   ├── NetworkProcessMonitor.cs     # 进程级 TCP/UDP 网速监控
│   │   └── StartupManager.cs            # 开机自启(HKCU\...\Run 注册表)
│   ├── Views/
│   │   ├── BoosterPanel.xaml / .xaml.cs # 管理面板(加速 / 网速 / 设置 三个 Tab)
│   │   ├── ExitConfirmDialog.xaml / .xaml.cs   # 退出确认对话框
│   │   ├── MultiKillConfirmDialog.xaml / .xaml.cs  # 批量结束进程确认对话框
│   │   └── ToolTipPopup.xaml / .xaml.cs # 清理结果气泡提示
│   ├── Converters/
│   │   └── ValueConverters.cs           # XAML 值转换器
│   ├── bin/Release/net45/                # 编译产物输出目录
│   │   ├── 内存清理加速器.exe            # 主程序
│   │   ├── MemoryCore.dll                # 后端 DLL
│   │   └── System.ValueTuple.dll         # net45 ValueTuple backport
│   └── obj/                             # 临时构建产物(可删除)
│
├── 软件图/                                # UI 截图素材
│   ├── 主菜单页面.jpg
│   ├── 加速球.jpg
│   ├── 网络流量监视.jpg
│   └── 设置页面.jpg
│
├── .vs/                                  # Visual Studio 用户配置缓存(可删除)
├── MemoryBooster.sln                    # Visual Studio 解决方案
├── README.md                            # 原开发文档(v2.0)
├── DEV_DOC.md                            # 与 README.md 同步的开发文档
├── README2.md                            # 本文档
├── favicon.ico                           # 原始图标文件
└── 内存清理加速球2.0.zip                 # 预编译打包发布文件

关键模块说明

路径 作用
MemoryCore/MemoryCore.cpp 所有 Win32 API 调用入口,C 接口导出,无名称修饰
MemoryBooster/Services/NativeInterop.cs C# P/Invoke 声明层,结构体与 C++ 一一对应
MemoryBooster/Services/MemoryService.cs 内存 / 进程业务逻辑,含前台窗口枚举与强力结束进程回退
MemoryBooster/Services/NetworkMonitor.cs 系统级网速(GetIfTable2,仅物理网卡)
MemoryBooster/MainWindow.xaml.cs 悬浮球交互与所有定时器(内存刷新 / 网速 / 自动清理 / 自身瘦身)
MemoryBooster/Views/BoosterPanel.xaml.cs 管理面板 UI 与进程列表滚动 / 选中持久化 / 右键菜单逻辑
MemoryBooster/App.xaml.cs 单实例 Mutex + 全局异常钩子 + 懒加载日志
MemoryBooster/Models/AppSettings.cs 设置项定义与 XML 序列化

七、可配置项一览

属性 类型 默认值 说明
AutoStart bool false 开机自启
AutoClean bool false 自动清理
AutoCleanIntervalMinutes int 10 自动清理间隔(分钟)
BallOpacity double 0.9 加速球透明度
BallSize double 70 加速球尺寸
BallSkin int 0 皮肤(0=绿,1=蓝,2=紫)
BallPositionY int -1 记忆纵坐标(-1=屏幕中间)
EnableNetMonitor bool false 网络监控总开关(关闭时不跑网速定时器,节省资源)
ShowForegroundProcs bool true 默认显示前台窗口进程置顶
MinimizeToTrayOnExit bool false 退出时最小化到托盘

源码地址:https://download.csdn.net/download/FL1623863129/90010549

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐