我在COM组件(使用vb6创建)上有一个包装器托管应用程序(.net),其中Com组件也使用本机c++动态链接库。
应用程序作为后台进程运行,应该全天候连续运行。应用程序在一段时间内运行良好,但在一段时间后崩溃。可能的原因可能是c++动态链接库或com中的内存泄漏,component.There是COM和c++动态链接库的大量代码。
由于我不熟悉com和c++,所以我尝试从托管应用程序的角度来解决这个问题。我正在考虑这样解决:如果托管应用程序开始消耗大量内存,那么我将重新启动托管应用程序。
1)如何以编程方式监控应用程序(托管+非托管)使用的总内存。
2)重新启动托管应用程序也会释放非托管资源。
3)是否有其他替代方法。
4)用于监控也使用非托管资源的托管应用程序的最佳调试工具有哪些。
如果我的解释不清楚,请再问我一次。
任何帮助都将不胜感激。
发布于 2010-07-25 07:53:17
我们如何以编程方式监控应用程序(托管+非托管)使用的总内存。
使用性能计数器。在开发/测试中,最容易使用PerfMon
在后台收集数据(使用数据采集组),然后在Excel或类似的文件中分析结果。
如果您需要在生产使用中继续这样做,应用程序可以自己读取性能计数器(使用System.Diagnostics.PerformanceCounter
和相关类)。
2)将重新启动托管应用程序,还会释放非托管资源。
是。
3)是否有其他替代方法。
是:解决问题。
如果COM组件或C++库真的泄漏了,那么这些确实需要修复(如果以前只用于短暂的进程,泄漏可能已经存在很长时间了)。
通过使用本机堆,您可能会遇到.NET托管堆和GC之间的交互。托管GC在存在内存压力时运行(即,否则将需要为进程获取更多内存才能完成分配)。如果托管包装器没有分配内存(或者分配的内存不多),那么它就没有理由运行GC。当您从.NET引用COM组件时,引用保存在本机包装类型中,当GC收集COM实例时,此包装释放COM实例(通过释放最后计数的COM引用)。
因此,如果GC不运行,则COM组件将不会被释放。只需让COM实例使用大量内存,提交的总进程内存就会开始增长。
有三种方法(按偏好递减):
当托管代码完成COM组件实例的使用时,如果COM实例已被one.
Marshal.ReleaseComObject
.
#3是最简单的,可以通过在运行几个小时后(例如在计时器上)强制执行完整的GC并查看内存使用性能计数器来确认此方法。如果是这种情况,则继续执行#1或#2。
(这基本上就是我在第一个.NET项目中发生的事情,大量非托管堆的交互被托管实例阻止释放,而托管实例由于缺乏托管内存而没有被收集。这种情况下的修复方法是向键COM组件添加一个额外的方法,以释放它持有的对象。)
https://stackoverflow.com/questions/3328421
复制相似问题