Tuning GC for Java audio applications

I noticed that when playing audio in Java, the marksweepcompact phase in GC is too long and leads to short silence, which is unacceptable So I need to use low pause GC I've tried parallel and CMS, and they seem to work better because I think the pause time is shorter and they don't collect completely as often as the default

So far, I have tested my program using the following options of parallelgc:

-XX:+UseParallelGC 
-XX:MaxGCPauseMillis=70

For concurrentmarksweep:

-XX:+UseConcMarkSweepGC
-XX:+CMSIncrementalMode
-XX:+CMSIncrementalPacing

I've also tried g1gc, but it's still experimental in Java 6 Options for two 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 case? Can these settings be optimized for optimal CPU performance and minimum memory usage?

In order to identify the pause, I recorded the time of writing audio data to the output line, usually between 92 and 120 milliseconds (I am writing 16384 bytes = ~ 92 milliseconds). When the advertisement runs full GC, it is 200 milliseconds:

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 my application's allocation mode is as follows: it loads a bunch of objects at startup, and then it starts playing. I guess most objects after that are allocated by GUI, because staring / pausing audio will not change GC graphics a lot This is what visual GC and parallel GC display together:

The chart starts at startup and I start playing Mark is

1) Sound delay and full GC, I think it adds the 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 application window and pause playback Nothing changed, and later it increased the size of the garden of Eden

3) I opened the window and started playing again

So I need to increase the allocated old Gen size? What do I do? I'm using - XX: newratio = 10 and - XX: newsize = 10m

thank you.

Solution

The log you provided is too small to provide real analysis, but it indicates that it took 200 milliseconds to do V. This means that your heap is too small or you have a memory leak In this case, you cannot adjust the GC algorithm Therefore, the rest of this reply is about how to get more information from the application and / or how to adjust the GC when eliminating memory leaks or having more problems

For the most part, a low pause means doing everything possible to keep the collection young

You really need to record exactly when writing starts and completes, and then associate it with STW pauses that occur in the JVM during this period, otherwise you actually don't know the cause or severity of the problem

What I do right away;

>Change the log record to output a single line (possibly starttime, Endtime, duration) that can be easily parsed by the script > add the printgcapplicationsstoppedtime and printgcapplicationconcurrenttime switches to obtain the record of each STW pause, not just GC events > use the latest JVM (i.e. 6u23), because there have been many improvements in hotspots in the past year or two, So a little older > you didn't say whether you are limited by memory, but if you can, I will certainly increase the heap size. 40m is very small, so you don't have enough space to play > run the application connected to visualgc, which can more fully understand the content of IMO, because you can view all different views at once

The key is to determine your lack of space and why The answer may lie in the distribution mode of your application, and whether it will produce a pile of transient objects so that you can quickly burn down your little Eden? The pause threshold is so high that you have to Ping objects through survivor space anyway, forcing frequent lifelong GCS (slow)?

There are some things to remember

>ICMs (incremental version) is applicable to 1 or 2 core machines. Does it describe your machine? How many cores do you have? You may just want to give up that option > CMS does have a single threaded stage (initial tag), which may hurt you > CMS usually likes heap more than other collectors, and your collectors are quite small

Edit after the visual GC chart is added to the problem. Because your memory is limited, you need to make full use of the space you have. The only way is to pass the repeated benchmark... Ideally, the repeated test

>You can use - XMN to specify the size of the younger generation, and the rest will be given for life. > You may want to adjust your use of survivor space so that you can make them fuller before they are exchanged and keep objects alive longer before they live for life

>- XX: targetsurvivorratio = 90 set it, so the survivor space needs to be 90% full before copying. Obviously, there needs to be a trade-off between the cost of copying and using the space > use - XX: printtenuringdistribution to display the size of each space and the way of things, You can also see this in visualgc > use - XX: maxtenuringthreshold to specify how many times an object can survive before the year-end collection (copied from one survivor space to another survivor space). For example, if you know that you only get temporary garbage or something that exists forever, it is wise to set it to 1

>You need to know what triggers a lifetime collection and consider taking steps to trigger it later

>For CMS, this may involve adjusting - XX: cmsinitiatingoccupancyfraction = < value >, set to 80, It will trigger 80% lifetime occupancy of CMS (Note: This is a bad thing, so you may prefer to let the hotspot manage this; if it is set too small, it will collect too frequent killing performance, if it is set too large, it may trigger too late, resulting in unplanned complete collection and corresponding long pause time

>If it's really an old collection that will hurt you, you need a low pause and then use CMS and parnew

Finally, get an analyzer and find out where the garbage comes from. You may find it easier to control the speed of garbage generation, and then put your power into a black hole that can be GC adjusted!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>