【发布时间】:2021-03-15 03:54:38
【问题描述】:
我有点 C# 的菜鸟。我已尝试在管理内存方面做正确的事情,但我现在遇到了“内存不足”错误。
更新 #2 12 月 5 日
我解决了! (有点)我不明白为什么,但是当我使用硬编码参数从我的测试应用程序中运行代码时,它工作得很好,但是当我使用对话框(基于 OokiDialog)来获取一些参数时,那就是内存没有得到释放。
所以,对话框似乎有些东西让它想要抓住这些对象,即使它们与对话框本身无关。
最后,我能够通过在它自己的任务中运行代码来“修复”问题:
Task taskA = Task.Run(() => MakeFiles(path, name));
taskA.Wait();
它让我再次工作,但我仍然喜欢一些关于为什么会这样的理论?
12 月 5 日更新
经过不断的挣扎,我决定将相关代码复制到一个测试项目中,我可以在那里进行实验。复制后,我运行它,惊讶地发现内存在每次迭代时先升后降。不再有“内存不足”!
仍在试图弄清楚如何/为什么。
12 月 4 日更新
我已经排除了 GIF 编码器。我把那部分代码注释掉了,内存还是涨涨涨涨的。
我正在加载图像并将它们的像素复制到 byte[] 数组中。在大多数情况下,我一直非常小心地使用局部变量,所以它们不应该持续存在。
有什么方法可以知道创建这些“StreamAsIStream [Strong Handle]”引用的对象或至少类对象? 原始问题
我已经对堆进行了一些分析,可以看到主要的罪魁祸首是 MemoryStreams。
我在几个地方使用 MemoryStream,但一直小心使用“使用”:
using (MemoryStream mem = new MemoryStream())
{
...
}
我注意到堆上的大多数流最终显示为:
StreamAsIStream [强句柄]
那个“强大的手柄”似乎是一个线索,也许? IE。因为它是一个强大的句柄,GC 不会清理它?
我尝试过显式处理流,然后强制进行垃圾回收,但无论我做什么,它们似乎仍然存在,最终我得到内存错误。
会不会是其他东西在内部使用 MemoryStream 而我找错地方了?
有什么想法或其他我可以看的吗?
【问题讨论】:
-
StreamAsIStream似乎是System.Windows.Media中使用的内部类,与MemoryStream无关 -
看看堆中空闲空间的分布情况。这些问题的一个常见原因是托管堆上有一个指向某些数据的本机指针,它会阻止堆被压缩(除了 LOH,.NET 总是在堆顶部分配)。
-
@TheGeneral 我认为你在做某事。有点刺激,看起来它可能是我使用 GifBitmapEncoder 的地方。仍在努力查看我做错了什么,但我会更新问题。
-
@Luaan 据我所知,我没有在我的代码中使用任何本机指针。还有其他可能的吗?例如。 GifBitmapEncoder.
-
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect();有帮助吗?
标签: c# memory-management memory-leaks garbage-collection memorystream