title: Tuning GC for Java audio application
body: <p>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.</p>
  
  <p>So far I've tested my program with the following options for ParallelGC:</p>
  
  <pre><code>-XX:+UseParallelGC 
  -XX:MaxGCPauseMillis=70
  </code></pre>
  
  <p>and for ConcurrentMarkSweep:</p>
  
  <pre><code>-XX:+UseConcMarkSweepGC
  -XX:+CMSIncrementalMode
  -XX:+CMSIncrementalPacing
  </code></pre>
  
  <p>I also tried G1GC, but it's still experimental in java 6. Options for both modes:</p>
  
  <pre><code>-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
  </code></pre>
  
  <p>Which GC is better in this situation? Can any of these settings be optimized for best CPU performance and minimal memory usage as well?</p>
  
  <p><strong>EDIT</strong> 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:</p>
  
  <pre><code>65.424: [Full GC (System) [PSYoungGen: 872K-&gt;0K(2432K)] [PSOldGen: 12475K-&gt;12905K(16960K)] 13348K-&gt;12905K(19392K) [PSPermGen: 15051K-&gt;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
  </code></pre>
  
  <p><strong>EDIT2</strong> 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:
  <img src="https://i.stack.imgur.com/CEJgH.png" alt="alt text"></p>
  
  <p>The graph starts at startup and I start playback. Labeled are</p>
  
  <p>1) sound delay and full gc, I think it increased Old size:</p>
  
  <pre><code>101.646: [Full GC [PSYoungGen: 64K-&gt;0K(6848K)] [PSOldGen: 15792K-&gt;12773K(19328K)] 15856K-&gt;12773K(26176K) [PSPermGen: 15042K-&gt;14898K(23808K)], 0.2411479 secs] [Times: user=0.19 sys=0.00, real=0.24 secs]
  </code></pre>
  
  <p>2) I open the app window and pause playback. Nothing really changes, a bit later it increases eden size.</p>
  
  <p>3) I open the windows and start playback again.</p>
  
  <p>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</p>
  
  <p>Thank you.</p>