更新NotifyIcon图标导致内存占用持续增长的问题求助
更新NotifyIcon图标导致内存占用持续增长的问题求助
兄弟,我之前也踩过这个一模一样的坑!咱们来捋清楚问题出在哪,以及怎么解决:
首先说原因:Icon是实现了IDisposable接口的资源,而NotifyIcon控件不会自动帮你释放旧的图标资源。更关键的是,你每次访问Properties.Resources.tray_empty或者tray_full的时候,这个属性都会返回一个全新的Icon实例,不是复用同一个对象——这就导致你每秒调用一次UpdateTrayIcon,就会多产生至少一个未被释放的Icon对象,内存可不就蹭蹭往上涨嘛!之前你用new System.Drawing.Icon(iconpath)的方式也是同理,每次new都是新实例,旧的实例没被Dispose,自然就堆在内存里了。
给你两个靠谱的解决方案,按需选:
方案一:复用Icon实例(推荐,性能最优)
既然你的图标只有“空”和“满”两种状态,完全可以提前把这两个Icon实例创建好,之后一直复用,不用每次都生成新的。
步骤如下:
- 在你的窗体类里定义两个私有字段,用来存复用的图标:
private Icon _trayEmptyIcon; private Icon _trayFullIcon;
- 在窗体的构造函数或者
Load事件里初始化这两个图标(只初始化一次):
private void MainForm_Load(object sender, EventArgs e) { // 从Resources加载并保存实例,这里指定和托盘图标一致的尺寸,避免缩放问题 _trayEmptyIcon = new Icon(Properties.Resources.tray_empty, notifyIcon.Icon.Size); _trayFullIcon = new Icon(Properties.Resources.tray_full, notifyIcon.Icon.Size); }
- 修改你的
UpdateTrayIcon方法,复用已有的图标,同时释放旧图标:
private void UpdateTrayIcon() { var info = GetRecycleBinInfo(); try { // 先把当前的旧图标存下来 Icon oldIcon = notifyIcon.Icon; // 复用提前初始化好的图标实例 notifyIcon.Icon = info.ItemCount == 0 ? _trayEmptyIcon : _trayFullIcon; // 释放旧图标资源 oldIcon?.Dispose(); } catch (Exception ex) { MessageBox.Show($"Error setting icon! {ex.Message}"); } }
- 最后别忘了在窗体关闭时,彻底释放这两个图标资源,避免残留泄漏:
private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { _trayEmptyIcon?.Dispose(); _trayFullIcon?.Dispose(); notifyIcon.Icon?.Dispose(); }
方案二:每次创建新实例但手动释放旧资源
如果你的图标内容需要动态变化(比如不是固定的空/满),必须每次创建新实例,那一定要记得在赋值新图标前,把旧的图标Dispose掉:
private void UpdateTrayIcon() { var info = GetRecycleBinInfo(); try { // 保存当前的旧图标 Icon oldIcon = notifyIcon.Icon; // 创建新的图标实例(这里也可以换成从文件路径加载) Icon newIcon = info.ItemCount == 0 ? new Icon(Properties.Resources.tray_empty, notifyIcon.Icon.Size) : new Icon(Properties.Resources.tray_full, notifyIcon.Icon.Size); // 赋值新图标 notifyIcon.Icon = newIcon; // 释放旧图标资源 oldIcon?.Dispose(); } catch (Exception ex) { MessageBox.Show($"Error setting icon! {ex.Message}"); } }
最后再提个小提醒:永远不要反复访问Properties.Resources里的Icon/Bitmap这类资源属性,每次访问都是新实例,很容易踩内存泄漏的坑。
按照上面的方法改完,你可以用任务管理器或者VS的内存诊断工具看看,内存应该就不会持续增长了,我之前就是这么解决的,亲测有效!
内容来源于stack exchange
相关产品推荐
相关产品推荐

