How to force garbage collection of object you can't dereference?
Asked Answered
E

2

9

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?

Egon answered 25/10, 2011 at 14:57 Comment(5)
I wonder - can you get hold of the reference via reflection?Paganism
Can you please post where you found the orphaned NetworkStream in the library? I just poked around the GetEventsMethod, but did not find a NetworkStream.Smoking
@HenningKrause I also gave Daren Thomas's approach a try, but reflecting would require a deeper investigation into the internals of ExchangeService and SubscriptionBase class which I chose to skip. Currently I've followed Salvatore's #1 for now and opened up a ticket with MS. We'll see what happens next...Egon
@SliverNinja Please post back the result you get from Microsoft. I'm very interested in this.Smoking
@HenningKrause The issue was never resolved by Microsoft...they never got back to me regarding the advisory assistance. Anyway...we kept using ANTS to profile our components in isolation and discovered that a SQL Exception in one thread was locking a NetworkStream to which EWS would conflict. Independently the components worked fine...however integrated together the SQLException would not release the calling thread resources and create a blocking call to which EWS would keep creating new NetworkStreams with each service call. Key Point: always cleanup resources - count on failures happening.Egon
C
6

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.

Criticaster answered 25/10, 2011 at 15:6 Comment(2)
Your dirty hack in 4 would work even if the field is not static. That assumes there is some object that shouldn't be “unreferenced”, but that (probably indirectly) keeps the problematic objects alive.Cripps
Yes of course, this method works in all circumstances but if you can just dereference an object that is not dereferencing other object and you can do that i would suggest this of course, without any dirty hack.Criticaster
G
0

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.

Guenevere answered 25/10, 2011 at 15:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.