gpt4 book ai didi

c++ - 如何在 .Net Web 应用程序中管理 COM 对象

转载 作者:行者123 更新时间:2023-11-28 08:33:53 24 4
gpt4 key购买 nike

必须从基于 .Net 服务器的 Windows 应用程序调用有时存在臭名昭著的内存泄漏问题的遗留 c++ 应用程序。 .Net 垃圾收集时间是不可确定的,有时 c++ 对象会“按时”销毁或未销毁,从而产生不可预测的结果,并且通常会使 c# web 应用程序崩溃。尽可能频繁地将 c++ 对象推送到垃圾收集堆栈的最佳方法是什么,但不要经常删除对 COM 对象的 .Net 引用。请记住,COM 对象可以生成子对象,因此 COM 对象的 .Net 引用计数可以通过函数调用而改变,不一定是实例化。

由于发生内存泄漏并且未清理 COM 对象,性能会下降,直到它变得如此缓慢以至于 IIS 自身跳闸几次然后崩溃。重新启动 IIS 可解决此问题,直到下一次。定期重新启动会有所帮助,但繁忙的一天可能会在工作日造成这种情况。

几年前,我不得不使用 .Net 1.1 解决这个问题。想知道其他人是否有我的解决方案或更好的解决方案。这不是 ASP.NET。它是一个 .Net dll。

最终的结果并不完全令人满意,网络服务器每隔几个月就会崩溃。

最佳答案

您问“将 C++ 对象尽可能频繁地插入垃圾回收堆栈的最佳方法是什么”,但 C++ 对象永远不会被垃圾回收。也许这样看...

您有一个实例化一堆 C++ 对象的进程。其中一些 c++ 对象实现了 COM 对象,因此它们的生命周期是通过 AddRef/Release 管理的。其中一些 COM 对象被导入到 .NET 世界中,并使用 RCW(运行时可调用包装器)进行包装。只有 RCW 是 .NET 对象并进入垃圾收集堆。

在您不进行任何干预的情况下,RCW 最终将被 GC 处理,当发生这种情况时,它将针对其底层 COM 对象执行释放操作。如果想立即释放COM对象,不等待GC,可以调用...

System.Runtime.InteropServices.Marshal.ReleaseComObject

...甚至是 FinalReleaseComObject,如果您确定它是您想要的。

回到您的问题:您想知道如何在不释放对 COM 对象的 .NET 引用的情况下删除 c++ 对象。由于 .NET 堆中不存在 c++ 对象,因此无法直接实现此目的。您可以从您的 COM 对象中公开一个删除其所有 C++ 对象的方法,然后简单地从您的 .NET 代码中调用它。但我想如果您的 COM 对象有可能识别所有泄漏的 C++ 对象,您已经在这样做了。

希望我已经解释了为什么没有办法实现您在问题中提出的建议,但是有很多工具可以帮助您找到并修复内存泄漏。我建议使用诸如 LeakDiag(在 StackOverflow 中搜索它)之类的工具来找出您的 C++ 代码泄漏内存的位置。

如果您使用的是 IIS6 或更高版本,实用的解决方案是配置应用程序池回收。您可以调整这些数字,以便在进程泄漏足够多的内存导致出现问题之前终止并重新启动进程,并且它通常以用户不会注意到任何停机时间的方式工作。

关于c++ - 如何在 .Net Web 应用程序中管理 COM 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/582663/

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