基于C#WPF实现的内存加速球清理类似360加速球内存清理
内存清理加速器 (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遍历系统进程。 - 内存信息:
GetProcessMemoryInfo取WorkingSetSize(工作集大小)与PrivateUsage(私有字节)。 - 可执行文件路径:
QueryFullProcessImageNameW获取进程映像完整路径。 - 受保护进程兼容:
OpenProcess失败时降级用PROCESS_QUERY_LIMITED_INFORMATION重试,使受保护进程(如系统服务)仍能取到部分信息。 - 前台进程识别:C# 侧通过
EnumWindows枚举所有顶层窗口,过滤条件为「可见 + 无 Owner + 标题非空」,再通过GetWindowThreadProcessId反查 PID,得到 PID → 主窗口标题的映射,从而区分前台应用与后台进程。 - 排序:按工作集大小降序排序。
1.3 CPU 占用率采样算法
CPU% 不能简单取瞬时值,需要 两次采样差值除以时间间隔 才有意义:
- 调用
GetProcessTimes获取进程的KernelTime与UserTime(FILETIME,单位 100 ns)。 - 两者相加得到总 tick 数,存入全局
g_cpuMap[pid] = { ticks, sampleMs }。 - 下次采样时计算
deltaTicks / 10'000'000.0秒,再除以elapsedSec × CPU 核数,归一化到 0–100%。 - 每个 PID 维护独立的
lastSampleTime,避免新出现进程首次读数被放大、长时间间隔后读数被过度放大,行为与任务管理器一致。 - 每轮采集结束后用本次见过的 PID 集合
swap替换旧表,让已退出进程条目自动淘汰,避免 map 无限增长。
1.4 系统内存占用百分比
直接调用 GlobalMemoryStatusEx,读取 MEMORYSTATUSEX.dwMemoryLoad(操作系统给出的物理内存占用百分比)。悬浮球颜色按阈值切换:<50% 绿 → 50–80% 黄橙 → >80% 红。
1.5 网速监控算法
系统级总速率 GetNetTotalStats
- 调用
GetIfTable2枚举所有网卡,仅累加 物理网卡(以太网 / Wi-Fi / WMAN / WWAN),跳过 loopback 与 tunnel / 虚拟网卡(WSL / Hyper-V / VMware / VPN),避免虚拟交换机镜像物理网卡字节导致的重复计数。 - 维护全局
{ lastSampleMs, lastIn, lastOut },本次累计值与上次差除以时间间隔得到 bytes/s。 - 时间间隔小于 50 ms 时按 50 ms 计,避免除零或异常放大。
进程级 TCP 速率 GetPerProcessNetStats(需管理员权限)
通过 TCP ESTATS(Extended Statistics)API 实现按进程的字节级速率统计:
GetExtendedTcpTable枚举所有 TCP 连接(v4 + v6),每条连接由四元组(本地/远端 地址 + 端口)唯一标识。- 维护全局
g_v4Conns/g_v6Conns两个 map,键为四元组,值为ConnState { pid, prevIn, prevOut, lastSeenMs }。 - 新连接出现时调用
SetPerTcpConnectionEStats启用 ESTATS 数据采集,读一次基准DataBytesIn / DataBytesOut。 - 已存在连接每次调用
GetPerTcpConnectionEStats读累计字节,与上次值做差累加到对应 PID 的聚合表。 - 无管理员权限时 ESTATS 启用失败,仍统计 TCP / UDP 连接数但跳过字节速率。
- 超过 10 秒未见的连接从 map 中过期清除,防止表无限增长。
- UDP 连接计数通过
GetExtendedUdpTable完成(仅计数,无字节级统计)。
1.6 单实例运行算法
启动时创建命名 Mutex Local\MemoryBooster.SingleInstance.{固定GUID}:
createdNew == true→ 本实例为首发,继续启动;退出时ReleaseMutex+Dispose。createdNew == false→ 已有实例运行,弹窗提示后立即Shutdown。
Local\ 前缀限定当前用户会话,避免跨用户冲突;GUID 后缀避免与同名产品混淆。
1.7 设置持久化算法
使用 XmlSerializer 将 AppSettings 序列化为 XML,存于 %APPDATA%\MemoryBooster\settings.xml。Save / 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,避免新增前台进程把用户视线挤走;右键菜单弹出前通过 ContextMenuOpening 把 SelectedItem 拨回当前红色选中项,确保菜单始终针对当前选中进程操作。
二、环境要求
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 直接使用预编译产物(推荐)
仓库已附带预编译产物,无需构建:
- 解压根目录压缩包
内存清理加速球2.0.zip,或将 MemoryBooster/bin/Release/net45/ 下两个文件拷贝到任意可写目录:内存清理加速器.exeMemoryCore.dll
- 两个文件 必须放在同一目录,否则 P/Invoke 会因找不到 DLL 而抛
DllNotFoundException。 - 双击
内存清理加速器.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\
四、运行步骤
- 启动:双击
内存清理加速器.exe。首次启动会在屏幕右侧出现悬浮加速球(仅露出 14px)。 - 唤出加速球:将鼠标移至屏幕右边缘附近,加速球自动滑出。
- 一键清理:左键单击加速球,触发全量工作集清理,清理完成后弹出气泡显示「清理进程数 / 释放字节数」。
- 打开管理面板:右键单击加速球,打开管理面板,包含三个 Tab:
- ⚡ 加速:内存占用百分比 + 一键加速按钮 + 进程列表(名称 / 内存 / CPU / 复选框)+ 搜索 + 排序下拉 + 显示路径 / 显示前台窗口进程复选框 + 清理 / 结束进程按钮 + 右键菜单(结束进程 / 打开文件位置 / 复制路径)。
- ⇅ 网速:上传 / 下载实时速度 + 累计流量(可通过启用开关关闭整个网络监控节省资源)。
- ⚙ 设置:开机自启、自动清理、清理间隔、网络监视开关、透明度、皮肤切换、关于信息、退出按钮。
- 拖拽定位:左键按住加速球可上下拖动,Y 坐标自动保存到设置;下次启动恢复。
- 退出:右键面板「设置」Tab → 退出按钮(如开启了「最小化到托盘」则会先弹确认对话框)。
4.1 运行时生成文件
| 文件 | 路径 | 说明 |
|---|---|---|
| settings.xml | %APPDATA%\MemoryBooster\settings.xml |
用户设置 |
| error.log | exe 同目录(可写时)或 %LocalAppData%\MemoryBooster\error.log |
异常日志(仅首次异常时才创建) |
五、注意事项
- DLL 与 EXE 必须同目录:
MemoryCore.dll是 P/Invoke 依赖,缺失会抛DllNotFoundException。 - 必须 64 位系统:
MemoryCore.dll为 x64 编译,无法在 32 位系统加载。 - 权限要求:
- 普通用户权限下,仅能清理自身进程工作集;其他进程因
OpenProcess被拒而跳过。 - 清理全部进程内存、查看进程级 TCP 网速需要
SeDebugPrivilege与管理员权限。
- 普通用户权限下,仅能清理自身进程工作集;其他进程因
- DLL 导出名称:MemoryCore.h 中所有函数必须在
extern "C"块内,避免 C++ 名称修饰导致 C# 找不到入口点。可用dumpbin /exports MemoryCore.dll验证导出符号。 - 结构体对齐:C++ 与 C# 两侧必须都用
pack=1,否则字段偏移不一致导致数据错乱。 - .NET Framework 4.5 兼容性限制:
- net45 原生无
ValueTuple→ 项目已通过System.ValueTuple 4.5.0NuGet 包 backport。 - 不能使用
nullable reference types(string?)。 - 不能使用
Environment.ProcessPath(用Assembly.GetExecutingAssembly().Location)。 LangVersion=latest下 file-scoped namespace / record 等纯 C# 语法糖仍可用。
- net45 原生无
- 单实例:多开会被 Mutex 拦截并弹窗退出;若进程异常残留 Mutex,重启系统或
taskkill /f /im 内存清理加速器.exe即可恢复。 - 网速统计准确性:系统级总速率仅聚合物理网卡,已自动排除 WSL / Hyper-V / VMware / VPN 等虚拟网卡的重复计数;进程级速率依赖 TCP ESTATS,必须以管理员身份运行,否则只能显示连接数无法显示字节速率。
- DataGrid 兼容性:WPF DataGrid 虚拟化 +
GroupStyle在快速滚动时存在已知 NRE 崩溃,本项目用IsSectionBreak字段 + DataTrigger 画分割线替代分组;路径列绑定ProcessInfo.PathVisibility而非RelativeSource AncestorType=Window,避免容器回收瞬间触发 NRE。修改进程列表 UI 时务必保持这两处约定。 - 日志懒加载:正常运行不会产生
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
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)