1

我用 C# 在 WPF 中开发了一个应用程序。该应用程序包括用于在特定窗口中显示相机的第三方 dll。

通常应用程序在没有相机对象(非托管对象)的情况下占用 90 MB - 135 MB 的内存。即,我在设计和代码页(xaml 和 xaml.cs)中删除了所有重新设置相机对象的代码。内存增加并停止在一个最大值。

如果我在应用程序中使用相机对象,内存会逐渐增加。当我每次打开相机窗口时,内存会逐渐增加,比如 135 MB 141 MB,143 MB ......

我已经在所有必要的地方使用了GC.CollectUsing语句来清除托管内存。我无法减少或停止内存增加。

如何解决这个问题?

任何建议将不胜感激

提前致谢。

4

3 回答 3

2

使用GC.Collect通常不会减少您的内存占用。停止调用它,您可能会看到一些改进。

更笼统地说,您不必太担心 .NET 应用程序的占用空间(尤其是当您通过任务管理器监视它时!)。.NET 运行时将在需要时释放内存 - 例如在压力下或空闲时 - 因此您看到的值不一定表明它正在使用更多内存 - 它只是暂时保留的内存。

一个可以证明这一点的小测试:当您最小化您的 .NET 应用程序时会发生什么?很多时候,您会看到任务管理器中的内存使用量急剧下降,并且在您重新显示窗口时不会立即恢复。

于 2011-10-10T07:30:53.250 回答
1

非托管相机组件是否有 C# 包装器?如果是这样,它是否实现了 IDisposable?确保您处理相机对象(如果已包装)将在非托管代码中调用其析构函数

非托管代码是否通过 DLL 导入连接到您的 C# 代码?如果是这样,请确保您正在调用所有“Close()”类型的方法来释放 C# 中的内存。我主张将相机组件包装在您自己的实现 IDisposable 的 .NET 类中,以便整齐地打包它

您是否订阅了任何 .NET 事件而不是取消订阅?例如 Camera.ImageReceived += new EventHandler... 保留对 .NET 事件的订阅可能会导致细微的内存泄漏,因为 GC 在有对象引用时无法收集对象(通过事件订阅)

最后,检查内存泄漏的粗略测试是让您的应用程序在夜间运行,并执行多个创建/删除相机窗口操作。看看你第二天是否得到 OutOfMemoryException。正如之前的海报所提到的,任务管理器不会准确地报告 .NET 应用程序的内存使用情况,但严峻的测试是 GC 最终会释放内存还是无限期地增长?

于 2011-10-10T09:55:14.827 回答
1

看来您已经回答了自己的问题

如果我在应用程序中使用相机对象,内存会逐渐增加。当我每次打开相机窗口时,内存会逐渐增加,比如 135 MB 141 MB,143 MB ......

我已经在所有必要的地方使用了 GC.Collect 和 Using 语句来清除托管内存。我无法减少或停止内存增加。

如上所述,GC.Collect 只对托管对象执行垃圾收集,而不是非托管对象。我假设内存泄漏来自您使用的相机对象,而不是来自托管代码。那你为什么还要怪 GC.Collect 导致高内存上升呢?

这就是为什么我将责任归咎于相机对象:

通常应用程序在没有相机对象(非托管对象)的情况下占用 90 MB - 135 MB 的内存。即,我在设计和代码页(xaml 和 xaml.cs)中删除了所有重新设置相机对象的代码。内存增加并停止在一个最大值。

如果我在应用程序中使用相机对象,内存会逐渐增加。当我每次打开相机窗口时,内存会逐渐增加,比如 135 MB 141 MB,143 MB ......

然后你应该调查你使用的相机控制。很明显,罪魁祸首是相机控制。

于 2011-10-10T09:35:56.603 回答