You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

更新NotifyIcon图标导致内存占用持续增长的问题求助

更新NotifyIcon图标导致内存占用持续增长的问题求助

兄弟,我之前也踩过这个一模一样的坑!咱们来捋清楚问题出在哪,以及怎么解决:

首先说原因:Icon是实现了IDisposable接口的资源,而NotifyIcon控件不会自动帮你释放旧的图标资源。更关键的是,你每次访问Properties.Resources.tray_empty或者tray_full的时候,这个属性都会返回一个全新的Icon实例,不是复用同一个对象——这就导致你每秒调用一次UpdateTrayIcon,就会多产生至少一个未被释放的Icon对象,内存可不就蹭蹭往上涨嘛!之前你用new System.Drawing.Icon(iconpath)的方式也是同理,每次new都是新实例,旧的实例没被Dispose,自然就堆在内存里了。

给你两个靠谱的解决方案,按需选:

方案一:复用Icon实例(推荐,性能最优)

既然你的图标只有“空”和“满”两种状态,完全可以提前把这两个Icon实例创建好,之后一直复用,不用每次都生成新的。

步骤如下:

  1. 在你的窗体类里定义两个私有字段,用来存复用的图标:
private Icon _trayEmptyIcon;
private Icon _trayFullIcon;
  1. 在窗体的构造函数或者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);
}
  1. 修改你的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}");
    }
}
  1. 最后别忘了在窗体关闭时,彻底释放这两个图标资源,避免残留泄漏:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 07:39:36