3

I am experimenting with cross-AppDomain objects, and found one quite strange thing.

When I call a remote method, which is allocating a MemoryStream object and returning it's reference (and which is immediately disposed by the caller), memory usage is quite significantly increasing and is not dropping down, even after calling GC.Collect().

On the calling method which returns new String or byte[] object every time, there is no leak.

The Memory profiler shows that most live objects are of type Char[] and String (in case of MemoryStream).

The question is - did I misunderstand something, and remote calls are not so simple as inheriting from MarshalByRefObject?

Mark Hall
  • 53,938
  • 9
  • 94
  • 111
aldem
  • 191
  • 11
  • Post some code. You cannot pass references between AppDomains. – H H Sep 04 '11 at 20:59
  • @Henk, what is the correct terminology for remote references then (the ones you get when transparently passing [ObjRef](http://msdn.microsoft.com/en-us/library/system.runtime.remoting.objref.aspx) instances accross boundaries)? – Lucero Sep 04 '11 at 21:02
  • @Henk, I call it "reference" simply because it is MarshalByRefObject - of course I do know that there are no "real" references involved. The code for remote method is dead simple: `Stream GetStream() { return new MemoryStream(Encoding.ASCII.GetBytes("Somestring"));}`, and I call it (in another AppDomain) like `remote.GetStream().Dispose()` – aldem Sep 04 '11 at 21:36

1 Answers1

3

Remote calls are as easy - but object lifetime and garbage collection are not as simple.

You should read a bit on leases and sponsorships.

Lucero
  • 59,176
  • 9
  • 122
  • 152
  • does it mean that even explicitly disposed object will not be collected immediately (or soon enough)? I've some settings for LifeTimeServices in my code, it doesn't really help. – aldem Sep 04 '11 at 21:37
  • OK, I found why the settings didn't work - they have to be changed in host domain, so now everything is collected as needed. Thanks for the hint :) – aldem Sep 04 '11 at 21:49
  • Though, now, I would like to know - is there any simple way to explicitly mark object as unused? Like in my example - when my remote stream is read, I could dispose it so it will be collected sooner, disregarding defaults. – aldem Sep 04 '11 at 21:53
  • @aldem, I haven't done that before, but I guess that you could use a very short-lived lifetime by default and register a sponsor on the object which controls the lifetime. The sponsor can be unregistered on the `ILease` interface, which should enable a more controlled distributed GC behaviour. Worth a read is also [this FAQ article](http://www.thinktecture.com/resourcearchive/net-remoting-faq/lifetime). – Lucero Sep 05 '11 at 09:57
  • This post has been flagged for removal because it is a link-only post (whose link is now broken). Could you please update this answer so it answers the question without requiring the reader to click through a link? – josliber Jan 30 '16 at 20:47
  • 1
    @josilber, I have fixed the link to point to a version archived. However, I'm not going to change the answer because the question is too unspecific to give a short answer; I cannot sensibly reproduce all the information found in the article without actually copying it. If you feel like removing the post - I don't care really. – Lucero Jan 30 '16 at 23:21