如何强制垃圾收集无法取消引用的对象?

发布于 2024-12-12 00:10:47 字数 481 浏览 0 评论 0原文

我们正在使用 EWS 托管 API,它会在给定的时间间隔后轮询 MS Exchange 是否有新邮件消息。每次调用轮询调用 (PullSubscription.GetEvents()) - Microsoft 的 API 无法正确处理 NetworkStream 并导致内存按比例增加。之前此处讨论过,但从未解决。使用 ANTS Profiler,我们能够确定哪些对象在内存中持续增长并隔离问题。

现在问题已被隔离 - 有没有办法处理在我们没有引用的外部 API 中创建的 NetworkStream? GC.Collect() 似乎没有处理它,因为它仍然有一个活动引用。我们可以做什么来清理悬空引用?是否有一些包装器可以用来强制清理他们有缺陷的 SDK?

We are using EWS Managed API which polls MS Exchange for new mail messages after a given interval. With each invocation of the polling call (PullSubscription.GetEvents()) - Microsofts API is failing to properly dispose the NetworkStream and causes memory to proportionately increase. This was previously discussed here, but never resolved. Using ANTS Profiler we were able to determine which objects were continuously growing in memory and isolate the issue.

Now that the issue has been isolated - is there a way to dispose of a NetworkStream created in an external API that we don't have a reference to? GC.Collect() doesn't seem to dispose it since it still has an active reference. What can we do to cleanup the dangling reference? Is there some wrapper we can use to force cleanup of their buggy SDK?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只有影子陪我不离不弃 2024-12-19 00:10:47

没有办法强制 GC 释放引用对象的内存!

首先,我建议联系微软本身以获取有关此错误的帮助。

其次,你是在谈论“处置”还是只是内存释放?它们是两个完全不同的东西。 (IDisposable 模式,终结器)。

第三,您可以取消引用引用这些对象的对象吗?

第四,一种可能的解决方案是使用反射器反编译出现问题的代码,了解一种可以到达保留引用对象的字段的方法,在代码中使用反射来访问私有字段并将它们放入无效的。
这是一个非常肮脏的黑客,但如果你没有其他办法,这是我唯一能想到的。仅当您无法以任何其他方式进行时才执行此操作。

There is no way to force GC to release memory for a referenced object!

First of all I would suggest to contact microsoft itself for help with this bug.

Second, are you talking about "disposal" or just memory release? They are two totally different things. (IDisposable pattern, finalizers).

Third, can u just dereference the object that are referencing these objects?

Fourth, one possible solution can be to decompile with reflector the code that is giving you the issue, understand a way you can arrive to the fields that are keeping the referenced objects, use reflection in your code to access the private fields and put them to null.
Is a very dirty hack, but if you have no other way is the only thing i can think of. Do this only if you cannot go in any other ways.

小苏打饼 2024-12-19 00:10:47

最简单的方法是运行将 SDK 连接到其自己的 AppDomain 的部分,并在完成后卸载 AppDomain。这将导致 AppDomain 中分配的所有内存被释放。

但您需要在项目中添加一些工作,因为您只能与 AppDomainMarshalByRef 对象交换或标记为 serilized

这还允许您监视 AppDomain 消耗的内存量。因此,您可以创建 AppDomain,在其中运行有问题的 SDK,如果它达到内存消耗的特殊限制,您可以卸载它。

The most easy way would be running the part the is interfacing the SDK into its own AppDomain and after your are done unload the AppDomain. This will cause all the memory allocated in the AppDomain to be freed.

But you will need add some work to your project since you can only interchange with an AppDomain the a MarshalByRef object or marked as serilizable.

This will also allow you to monitor the amount of memory consumed by the AppDomain. So you can create your AppDomain, run the buggy SDK in it and if it reaches a special limit of memory consumption you can unload it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文