I've noticed that when playing audio in java, MarkSweepCompact stage in gc is too long and results in short periods of silence, which is unacceptable. So I need to use a low pause gc. I've tried Parallel and CMS, they seem to work better because I suppose the pause is shorter and they don't do full collection as often as the default one.
So far I've tested my program with the following options for ParallelGC:
and for ConcurrentMarkSweep:
-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing
I also tried G1GC, but it's still experimental in java 6. Options for both modes:
-Xms15m -Xmx40m -XX:+UnlockExperimentalVMOptions -XX:+CMSClassUnloadingEnabled -XX:+TieredCompilation -XX:+AggressiveOpts -XX:+UseAdaptiveSizePolicy -Dsun.java2d.noddraw=false -Dswing.aatext=true -XX:MaxPermSize=25m -XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=10
Which GC is better in this situation? Can any of these settings be optimized for best CPU performance and minimal memory usage as well?
EDIT To recognize the pause I record time to write audio data to the output line, usually it's between 92 to 120 ms (I'm writing 16384 bytes = ~92ms), ad when Full GC is run, it's 200+ ms:
65.424: [Full GC (System) [PSYoungGen: 872K->0K(2432K)] [PSOldGen: 12475K->12905K(16960K)] 13348K->12905K(19392K) [PSPermGen: 15051K->15051K(22272K)], 0.2145081 secs] [Times: user=0.20 sys=0.00, real=0.21 secs] Was writing 16384 bytes, time to write 263 ms
EDIT2 Allocation pattern for my app is the following: it loads bunch of objects at startup, then it starts playing and I guess most of the objects after that are allocated by the gui, because staring/pausing the audio doesn't change the GC graph much. This is what visualgc shows with parallel gc:
The graph starts at startup and I start playback. Labeled are
1) sound delay and full gc, I think it increased Old size:
101.646: [Full GC [PSYoungGen: 64K->0K(6848K)] [PSOldGen: 15792K->12773K(19328K)] 15856K->12773K(26176K) [PSPermGen: 15042K->14898K(23808K)], 0.2411479 secs] [Times: user=0.19 sys=0.00, real=0.24 secs]
2) I open the app window and pause playback. Nothing really changes, a bit later it increases eden size.
3) I open the windows and start playback again.
So I need to increase allocated Old Gen size? How do I do that? I'm running with -XX:NewRatio=10 and -XX:NewSize=10m