6

Hi have quite a problem with an Service running WCF in duplex-mode. It leaks memory (not much but it's about 80MB a day) and after having a memory-profiler running alongside the service for 24 hours I found most of the memory sitting in byte[] referenced by quite a mess but I most references end in something like this: one path holding the byte[] - array and the "root" looks like this: root

I too see lots of ServiceChannel (around 200) comming (I think) from the callback-channels.

I'm rather sure that I only hold 1 of those for each of the connected clients.

Overall my problem seems to be almost the same as this: memory leak in silverlight Wcf implementation but on the server-side.

I even tried the [MTAThread] thing mentioned here: WCF service leaks handles and memory when a client times out but it just don't solve the problem.

I just don't think that the problem is with my code as I wrap the callback-channels after getting it with OperationContext.Current.GetCallbackChannel<IServiceConnectorCallback>() in one of my own objects and those don't leak (there is only one of those for each clients in memory at any given snapshot) - sure I reset those callbacks on several occasions as the channel might change (clients losing the connection or reconnecting) but I don't have a way of disposing the old references so I only drop them and the GC should do it's job on them.

I do use PerCall on my service so I don't have any handle to those objects in my code at all.

I really have no clue at how I can handle this aside from restarting the service every few days - a solution I don't want to probose right now :(

So please give me some help/hints on this - thank you very much!

Community
  • 1
  • 1
Random Dev
  • 51,810
  • 9
  • 92
  • 119
  • Do you see a higher memory gain if the clients fault alot and you have to recreate the callback channel? Do you `Abort` the callback channel if the client has gone away? – Richard Blewett Feb 21 '12 at 07:28
  • It's hard for me to tell but this might be the case - and no I don't abort the channel on the server (how can I do this - using `GetCallbackChannel` I only get `T` - do you have to cast this into some kind of proxy?) – Random Dev Feb 21 '12 at 07:31
  • 1
    You should be able to cast it to `IClientChannel` – Richard Blewett Feb 21 '12 at 08:22
  • thank you - found this on another post and am implementing this right now. When I get you right, I should call .`Abort` on the Clientchannel if the Faulted-Event is raised right? - I think I can even improve on my code by handling the .Close as well so I don't have run into trouble by posting to a disconnected client anymore. – Random Dev Feb 21 '12 at 08:47
  • am testing this right now - I think I have to wait some hours to see if this is ok - BTW: should I call dispose on closed/faulted `IClientChanels`? – Random Dev Feb 21 '12 at 09:26
  • what I can tell already is that there ARE a lot of faulted-callback channels - I guess this is because the clients are moving around and chaning accesspoints quite a bit – Random Dev Feb 21 '12 at 09:29
  • I'm using a NetTcpBinding for this – Random Dev Feb 21 '12 at 10:25
  • Sadly it seems like this does not fix the problem - maybe I should try to Dispose the Clientchannels? – Random Dev Feb 21 '12 at 11:56
  • `Dispose` on the channel simply calls `Close` - you still need to Abort a faulted channel. Are you storing the client channel and retrieving it from the `OperationContext` every time? if so you should `Close` it when you're finished with it after each time you use it – Richard Blewett Feb 21 '12 at 14:04
  • yes I learned the hard way that Dispose is not a good idea - and yes I'm retrieving/setting the channel on every call I get from each client so I can update them on demand. But as far as I can tell the channel will be the same on every call so I only replace them if not so - I don't close the channel in this case right now as the old channel should have been faulted/closed anyhow but I guess I could try to add a guarded (only on State=Opened) call to close there if you think this is the way to go – Random Dev Feb 21 '12 at 14:32
  • @Richard: please post your comment in answer form - seems like this solves the problem (Abort each Clientchannel if a new one is registered) or at least the majority of it - thank you very much! – Random Dev Feb 24 '12 at 05:01
  • @CarstenKönig what memory analyzer do you use ? – Stephane Rolland Oct 22 '14 at 16:31
  • @StephaneRolland I don't need them very often but I did buy a licence for the ANTS MemoryProfiler from RedGate - but most I did look at back than had a trial version and I would recommend trying those and decide for yourself. – Random Dev Oct 22 '14 at 18:52

1 Answers1

7

When a session based channel faults a call to Close will throw an exception. However, there are proxy side resources that are not cleaned up in this case and these are only cleaned up when you Abort the faulted channel

Make sure that when you replace a faulted channel that you Abort the old one first

Richard Blewett
  • 6,089
  • 1
  • 18
  • 23