Java音频应用程序的GC调优
我注意到在java中播放音频时,gc中的压缩阶段太长,导致短时间的沉默,这是不可接受的。所以我需要使用低暂停gc。我试过Parallel和CMS,它们似乎工作得更好,因为我认为暂停时间更短,而且它们不像默认的那样经常进行完整收集 到目前为止,我已经使用以下ParallelGC选项测试了我的程序:Java音频应用程序的GC调优,java,performance,audio,garbage-collection,Java,Performance,Audio,Garbage Collection,我注意到在java中播放音频时,gc中的压缩阶段太长,导致短时间的沉默,这是不可接受的。所以我需要使用低暂停gc。我试过Parallel和CMS,它们似乎工作得更好,因为我认为暂停时间更短,而且它们不像默认的那样经常进行完整收集 到目前为止,我已经使用以下ParallelGC选项测试了我的程序: -XX:+UseParallelGC -XX:MaxGCPauseMillis=70 对于ConcurrentMarkSweep: -XX:+UseConcMarkSweepGC -XX:+CMSI
-XX:+UseParallelGC
-XX:MaxGCPauseMillis=70
对于ConcurrentMarkSweep:
-XX:+UseConcMarkSweepGC
-XX:+CMSIncrementalMode
-XX:+CMSIncrementalPacing
我也尝试过G1GC,但它在Java6中仍然是实验性的。两种模式的选项:
-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
在这种情况下,哪个GC更好?是否可以对这些设置中的任何一个进行优化,以获得最佳的CPU性能和最低的内存使用率
编辑识别将音频数据写入输出线的暂停记录时间,通常在92到120毫秒之间(我写入16384字节=~92毫秒),如果运行完整GC,则为200毫秒以上:
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我的应用程序的分配模式如下:它在启动时加载一堆对象,然后开始播放,我猜之后的大多数对象都是由gui分配的,因为启动/暂停音频不会对GC图产生太大的改变。这是visualgc使用并行gc显示的内容:
图形从启动时开始,我开始播放。有标签的是
1) 声音延迟和完整gc,我认为它增加了旧尺寸:
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) 我打开应用程序窗口并暂停播放。没有什么真正的改变,过了一会儿,它增加了伊甸园的大小
3) 我打开窗口,再次开始播放
所以我需要增加分配的旧发电机尺寸?我该怎么做?我使用-XX:NewRatio=10和-XX:NewSize=10m运行
谢谢。这意味着有太多的对象被提升出了eden空间,因为主GC不必处理太多。您可以使用-XX:NewRatio增加给新一代的空间比例。尝试10并向上移动。
更好的方法是,研究如何减少程序中对象的引用范围。好的,简而言之,系统上有一个非功能性需求,但没有指定该需求。“正确”的答案是使用具有实时能力的JVM实现。但大多数都很昂贵,我想你会接受99.9%的正确答案 首先,你要做的是找到一种测量这种中断的方法。否则,任何比较不同垃圾收集器的实验都注定是不可靠的 在这段介绍性陈述之后,让我们来谈谈您的问题: 您说过垃圾收集器在声音播放中引入暂停。你的选择是:
总结:如果你真的想摆脱这个问题,(1)找到一种方法来衡量它,(2)做实验,(3)找到根本原因,(4)解决根本原因,和(5)衡量你是否真正解决了这个问题。你提供的日志太小,无法提供真正的分析,但它说,由于旧的发电机基本上已经满了,它花了200毫秒做了一点v。这意味着您的堆太小或内存泄漏。在这种情况下,您无法对GC算法进行调优。因此,本回复的其余部分是关于如何从应用程序中获取更多信息和/或在消除内存泄漏或拥有更大堆后如何调优GC 在很大程度上,低暂停意味着尽一切可能保持集合仅为年轻集合 您确实需要准确地记录您开始和完成编写的时间,然后将其与JVM中在这段时间内发生的STW暂停相关联,否则您真的不知道问题的原因或严重程度 我会马上做的事情
- iCMS(增量)计划在1或2台核心机器上使用,这是否描述了您的机器?你们有多少核?你可能只想放弃这个选择
- CMS确实有一个单线程阶段(初始化标记),这可能会伤害你
- CMS通常比其他收集器更喜欢一个更大的堆,你的堆相当小
-XX:MaxHeapFreeRatio=10
-XX:MinHeapFreeRatio=10