当使用OpenFileDialog时如何释放内存?

4

Winform OpenFileDialog,每次打开它,内存都会增加,dispose()和OpenFileDialog = null无效,内存不会减少。

如何解决这个问题?

   private void btnLocalPicture_Click(object sender, EventArgs e)
    {
        OpenFileDialog ofdSelectPicture = new OpenFileDialog();
        ofdSelectPicture.Filter = "PicFile|*.jpg;*.png;*.jpeg;*.gif;*.bmp;*.tif";
        if (ofdSelectPicture.ShowDialog() == DialogResult.OK)
        {
            if (showPicture != null)
                showPicture.Dispose();
            showPicture = Image.FromFile(ofdSelectPicture.FileName);
            if (pbShowPicture.Image != null)
                pbShowPicture.Image.Dispose();
            pbShowPicture.Image = showPicture;
            path = ofdSelectPicture.FileName;
            WordTip.Visible = false;
            if (pbShowPicture.Image != null)
                picOK.Enabled = true;
        }
        ofdSelectPicture.Dispose(); //not working
        ofdSelectPicture = null;  //not working
        GC.Collect();
    }

1
你是如何测量内存消耗的?因为垃圾回收器不是确定性的,也不一定会将内存释放回操作系统,只有内存分析器才能真正反映出引用是否仍然保留着内存分配。 - spender
2
这取决于你是否发现了内存泄漏,或者这是gc的正常操作。在决定是否真正存在问题之前,您需要有效地进行测量。你是如何测量的???肯定所涉及的内存量是微不足道的吧?你打算打开多少个文件对话框? - spender
1
你永远不应该(必须)调用GC.Collect()。 - H H
2
如果打开文件对话框引起了额外的 DLL 加载,那么这部分内存直到应用域卸载时才会被释放。 - spender
1
你确定你看到的不是Image的内存吗?每次打开新图片时,内存消耗是否会无限增加?还是只有在第一张图片之后才会这样? - Jeppe Stig Nielsen
显示剩余6条评论
1个回答

7
您可以在“项目+属性”中的“调试”选项卡中勾选“启用非托管代码调试”选项,以查看程序运行时加载的DLL列表。这些DLL是在您的计算机上注册的Shell扩展,每个人都有自己喜欢的扩展,因此无法预测会得到什么。程序员通常会有很多扩展。
是的,这些扩展将在您的进程中消耗内存,因为这些DLL占用了虚拟内存地址空间的空间。但也因为这些DLL为自己的使用分配内存。一个编写不好的扩展程序肯定会泄漏内存。请注意,这些扩展所分配的内存始终是非托管内存,因此请确保您有一个好的工具来显示泄漏情况。像TaskMgr.exe这样的工具是不够好的。
关于此问题,您可以采取两种基本措施。第一种是忽略它,这个问题只出现在您的计算机上,其他用户可能不会遇到同样的问题。您不能修复泄漏,因为您没有扩展程序的源代码。或者您可以使用SysInternals的AutoRuns实用程序追踪问题制造者。它会显示已注册的Shell扩展,并允许您通过单击复选框来取消注册它们。

所以没有办法解决这个问题吗?我的老板让我解决这个问题,这让我很烦恼... - Jason Wong
有没有办法使用 OpenFileDialog 而不是 VS? - Jason Wong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接