gpt4 book ai didi

c# - 使用非托管资源

转载 作者:行者123 更新时间:2023-11-30 13:04:04 24 4
gpt4 key购买 nike

我使用第 3 方库,它是 native dll 的包装器。该库包含一个类型 XImage , XImage有一些属性和一个 IntPtr Data()方法。 XImage还实现了 IDisposable但我不知道它是否正确实现。

我得到很多XImage s 来自 TCP 连接并在 PictureBox 中将它们显示为电影.

我曾经将“XImage”转换为 System.Drawing.Image并在 PictureBox 中查看它们但我得到了AccessViolationException .

所以我围绕XImage做了一个包装称为 Frame .

public class Frame : IDisposable
{
public uint size { get; private set; }
private Image image;
public XImage XImage { get; set; }
public Image Image { get { return image ?? (image = GetBitmap(this.XImage)); } }
public DateTime Time { get; set; }

public Frame(XImage xImage)
{
this.XImage = xImage;
this.size = XImage.ImageBufferSize();
GC.AddMemoryPressure(size);
}


public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

~Frame()
{
Dispose(false);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
try
{
image.Dispose();
}
catch { }
finally
{
image = null;
}
try
{
MImage.Dispose();
}
catch { }
finally { XImage = null; }
}
GC.RemoveMemoryPressure(size);
}
}

并通过处理对 Frame 的引用我解决了 AccessViolationException .现在我有另一个问题,当我从 visual studio 运行程序时(F5 - 开始调试)一切正常,但是当我从 .exe 运行它时文件或(ctrl + F5 - 开始而不调试)内存使用量越来越大,直到我得到 OutOfMemoryException .(Biuld 配置:发布 - X86)。我该怎么办?

----编辑----

我发现 GC.AddMemoryPressureGC.RemoveMemoryPressure只是让垃圾收集更频繁地运行,我现在的问题是我有一些小对象可以处理大型非托管内存,而 GC 没有收集这些小对象。

---- 编辑 ----
打电话GC.Collect将在运行时解决问题,我设置了一个计时器并调用 GC.Collect定期,但它会使应用程序短时间卡住,所以我不想使用这种方法。

最佳答案

我发现 GC 有局限性,在非常大的压力和内存密集型应用程序下可能无法很好地工作。我有一个不直接对非托管资源、所有标准 .NET 组件执行任何操作的应用程序,它仍然会阻塞内存。它可以使用 GB 的 RAM,但不是因为巨大的内存需求,而是因为大对象的创建和销毁相对较快,而且显然不会经常收集。应用程序没有内存泄漏,因为它在强制收集时全部释放。看起来 GC 并不总是能够按时收集未使用的对象,即在 OutOfMemoryException 之前。它等待找到最佳时机,但在它做出决定之前为时已晚。当我定期强制收集时,应用程序运行没有问题。

值得一提的是,OutOfMemoryException 并不总是意味着您实际上没有可用内存。这也可能意味着没有足够大的连续内存块可用。在处理视频和图像时尤其如此。 GC 可能认为仍有大量可用内存,但对于您的应用程序来说它太零散了。我确信 GC 会考虑碎片,但它可能并不总是正确的。

如果您确定库不是问题所在,我的建议是尝试更多内存压力方法(AddMemoryPressureRemoveMemoryPressure)以帮助 GC 按时完成任务。它可能会解决您的问题,因为您使用的是非托管库,该库可能在​​ GC 背后处理大量内存。或者像使用 GC.Collect 一样进行操作。手动收集可能并不理想,但我相信在某些情况下它是合理的。当然,手动收集大量对象可能会对您的应用程序性能产生影响。

编辑

如果手动收集对性能的影响太大,请尝试使用 GC.Collect 的重载版本,让您有更多的控制权。

关于c# - 使用非托管资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10569988/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com