How to force garbage collection of object you can&

2019-04-21 09:04发布

问题:

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?

回答1:

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.



回答2:

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.