- Created Thursday, February 4th 2016 @ 18:39:19
The reason I ask is that I keep getting absolutely KILLED by garbage collection pauses that are hundreds of milliseconds long (if not full seconds long). I suspect it's probably just using the default configuration. If that's the case, would it be possible to enable the concurrent garbage collector? With only 500 ms per move it's pretty much impossible to survive some of these pauses without timing out.
If you would like, when I get home I suggest some specific settings that (I think) are more appropriate than the defaults for real-time applications like the bots.
- Created Friday, February 5th 2016 @ 05:19:23
I have done some messing around with the various GC flags and have had good results with:
I've also used the G1 collector (-XX:+UseG1GC) and that seemed to also work well, but I have not used it as much.
- Updated Friday, February 5th 2016 @ 07:34:42
I assume the JVM is runing on a single core here, so the best option is SerialGC (full stop to clean garbage). The options you've requested are not fair, because they are actively using multiple cores for garbage collection, while your application is running and producing garbage. This is the same as C++ strategy asking to run more threads for memory management purposes.
- Created Friday, February 5th 2016 @ 08:12:00
Have you thought about reusing old objects instead of creating/deleting them all the time?
DeveloperCreated Friday, February 5th 2016 @ 14:06:21
For now we are not going to change anything about it. You seem to be the first one experiencing problems, but I'll investigate it at a later point. Try to make your bot more efficient for the moment.
- Created Friday, February 5th 2016 @ 15:16:05
Thanks for the reply Jim. I worked around the issue for now.
@Bafegox: yeah, I've considered an object pool for my game tree nodes, but usually it shouldn't be necessary for such a lightweight objects. If I were running into this issue at work I would just switch to one of the GC configs I mentioned above and go about my merry way. Since that doesn't seem to be an option here, in the short term I resorted to just leaving more time unused in case I get whacked about the head by an oversized GC pause. I keep ~3 full seconds reserved. I'm also considering trying a scheme where I just don't clean out my game tree at all. No garbage == no garbage collection, at a cost of extra memory used. Since the games are so short I think it might be fine.
@chianti: The JVM is running on a 3 core system (as reported by the JVM at least) so the single-threaded assumption is not accurate. Even if it were, this situation is significantly different from your C++ example in that with C++ I would be the one controlling when to do the memory management and for how long. In Java there is no such control (short of explicitly calling System.gc() which is like cutting off your arm because your hands got dirty). Even on a single core system the concurrent and parallel GCs are dramatically more appropriate for real-time applications since they reduce the length (and in some cases frequency) of the uncontrollable GC pauses.
- Updated Thursday, April 7th 2016 @ 22:36:50
I've noticed that my bot sometimes times out, even with a fairly conservative permanent reserve of 500 ms. And it pretty much only times out when playing against one specific other bot, the bot of melsonator. Which is written in Java, just like mine.
Here's one of those games:
In round 25, my bot has 1002 ms left according to the system. According to the timing in my bot, it then takes it 488 ms to respond. In round 26 however, the system says there are only 505 ms left.
I get the feeling this is related to the fact that both bots are written in Java. Do you notice similar differences when you are playing my bot? I'm not using any pondering (thinking during the move of the opponent), but I do call a System.gc() right after I make a move. (I couldn't find the soap ;-)
- Created Friday, April 8th 2016 @ 03:50:04
I found that I usually have to leave well over a second held in reserve. A quick check shows that at the end of our games I have around 2-2.5 seconds left on the clock. My implementation seems to sometimes be very sensitive to garbage collection pauses and sometimes it runs like a champ, and I haven't really been able to nail down what changes cause problems.
I checked out the game you called out, and nothing looks out of the ordinary on my side. If it makes you feel better, I had a forced win on move 46. :)
I used to do a System.gc() between turns, but I found that it was performing worse than just keeping extra time on the clock and eating the full-length GCs that happen whenever the JVM decides.
- Created Friday, April 8th 2016 @ 10:37:03
My bot is written in C++ and I notices that it takes about 150ms more per turn when it plays against melsonator's bot. I increased the time to leave on the clock specifically not to loose on time against Jaeger :)
- Created Saturday, April 9th 2016 @ 23:04:32
Right, I did the exact same thing. Maybe this is because of pondering?
(In that case I could also calculate the decimals of pi during the turn of the opponent to improve my bot...)