6

I know there's tons of threads about this. And I read a few of them.

I'm wondering if in my case it is correct to GC.Collect();

I have a server for a MMORPG, in production it is online day and night. And the server is restarted every other day to implement changes to the production codebase. Every twenty minutes the server pauses all other threads, and serializes the current game state. This usually takes 0.5 to 4 seconds

Would it be a good idea to GC.Collect(); after serialization?

The server is, obviously, constantly creating and destroying game items.

Would I have a notorious gain in performance or memory optimization / usage?

Should I not manually collect?

I've read about how collecting can be bad if used in the wrong moments or too frequently, but I'm thinking these saves are both a good moment to collect, and not that frequent.

The server is in framework 4.0

Update in answer to a comment:

We are randomly experiencing server freezes, sometimes, unexpectedly, the server memory usage will raise increasingly until it reaches a point when the server takes way too long to handle any network operation. Thus, I'm considering a lot of different approaches to solve the issue, this is one of them.

bevacqua
  • 47,502
  • 56
  • 171
  • 285
  • Why do you want to call GC.Collect? Is there any issue? – Novitzky May 07 '11 at 22:39
  • Updated with the reason behind my question. – bevacqua May 07 '11 at 22:50
  • 3
    You see the issue but you don't know root cause and start to pick first thing that is obvious for you. Try to get the root cause (using memory profiling for example) and then finding appropriate solution will be much easier. – Andrey May 07 '11 at 22:58
  • @Andrey I did, and I thought I did. But that didn't solve the problem and the server is still randomly freezing. The information from mem/perf profiling wasn't really of help because I can't run the most complete ones, since the extra overhead is too much for the server to handle – bevacqua May 07 '11 at 23:19
  • @Nico take an hour. restrict amount of maximum connected users for that hour and make full blown profile session. – Andrey May 07 '11 at 23:28
  • @Andrey I wish it were that easy. When I say it's random, I mean the problem arises **really** randomly. It could take a pair of hours to manifest, or it could take two days. Given this random factor I assume it has something to do with a particular action users can perform in game, but it's really difficult to track down and pinpoint. I've been unsuccessfully trying to deal with this issue for months now – bevacqua May 08 '11 at 00:01
  • @Nico try to log suspicious user actions into database to find any correlation between memory peaks and actions. – Andrey May 08 '11 at 00:03
  • @Andrey the problem is that I have no clue where to look for suspicious actions, or what would qualify as "suspicious". I mean, virtually everything that the server does is in response to user actions, I suspect the freezes are user-triggered, somehow, but almost everything in the game server is user-triggered, so this suspicion doesn't really get me anywhere... – bevacqua May 08 '11 at 00:06

3 Answers3

12

The garbage collector knows best when to run, and you shouldn't force it. It will not improve performance or memory optimization. CLR can tell GC to collect object which are no longer used if there is a need to do that.

Answer to an updated part: Forcing the collection is not a good solution to the problem. You should rather have a look a bit deeper into your code to find out what is wrong. If memory usage grows unexpectedly you might have an issue with unmanaged resources which are not properly handled or even a "leaky code" within managed code.

One more thing. I would be surprise if calling GC.Collect fixed the problem.

Novitzky
  • 4,756
  • 3
  • 23
  • 27
  • Then why is the Collect method public at all? – bevacqua May 07 '11 at 22:46
  • Agree. Unless you're having a problem, don't mess with it. – Ortiga May 07 '11 at 22:46
  • 2
    @Nico, It is public mainly for testing purposes. Sometimes you need to test some code and see what will happen after to collection occurs so you need to be able to force it. – Novitzky May 07 '11 at 22:52
  • 2
    @Nico: http://stackoverflow.com/questions/478167/when-is-it-acceptable-to-call-gc-collect http://blogs.msdn.com/b/ricom/archive/2004/11/29/271829.aspx basically answer is that you never need it in production code. – Andrey May 07 '11 at 22:55
  • 2
    Can I hear a big "AMEN!!"? Novitzky pretty much nailed it. Calling `GC.Collect` will move all uncollected objects to gen 2, which makes them live only longer. So this will often make things just worse. – Steven May 07 '11 at 23:53
2

Every twenty minutes the server pauses all other threads, and serializes the current game state. This usually takes 0.5 to 4 seconds

If all your threads are suspended already anyway you might as well call the garbage collection, since it should be fairly fast at this point. I suspect doing this will only mask your real problem though, not actually solve it.

We are randomly experiencing server freezes, sometimes, unexpectedly, the server memory usage will raise increasingly until it reaches a point when the server takes way too long to handle any network operation. Thus, I'm considering a lot of different approaches to solve the issue, this is one of them.

This sounds more like you actually are still referencing all these objects that use the memory - if you weren't the GC would run due to the memory pressure and try to release those objects. You might be looking at an actual bug in your production code (i.e. objects that are still subscribed to events or otherwise are being referenced when they shouldn't be) rather than something you can fix by manually taking out the garbage.

If possible in this scenario you should run a performance analysis to see where your bottlenecks are and what part of your code is causing the brunt of the memory allocations.

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
1

Could the memory increase be an "attack" by a player with a fake/modified game-client? Is a lot of memory allocated by the server when it accepts a new client connection? Does the server handle bogus incoming data well?

remington123
  • 11
  • 1
  • 3
  • Yes, it could be. Though it's unlikely. No more memory than when creating a game item is allocated when a user connects. The server does handle bogus incoming data – bevacqua May 08 '11 at 01:21