我已经注意到,在Java中播放音频时,gc中的MarkSweepCompact阶段太长,导致短暂的静音期,这是不可接受的。所以我需要使用低暂停时间的gc。我尝试了Parallel和CMS,它们似乎工作得更好,因为我想暂停时间较短,而且它们不像默认的那样进行完整收集。
到目前为止,我已经使用ParallelGC的以下选项测试了我的程序:
-XX:+UseParallelGC
-XX:MaxGCPauseMillis=70
对于ConcurrentMarkSweep:
-XX:+UseConcMarkSweepGC
-XX:+CMSIncrementalMode
-XX:+CMSIncrementalPacing
我也尝试过G1GC,但仍在Java 6中处于实验状态。两种模式的选项:
-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字节=〜92ms),广告在运行Full 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运行
谢谢。
您提供的日志太小,无法提供真实的分析结果,但它说,由于旧发电机已基本满,它花了200毫秒完成了很少的时间。这意味着您的堆太小或发生内存泄漏。在这种情况下,您没有太多可以调整GC算法的操作。因此,本回复的其余部分是关于如何在消除内存泄漏或拥有更大堆之后如何从应用程序中获取更多信息和/或如何调整GC。
在很大程度上,低停顿意味着您将竭尽所能将这些收藏仅保留为年轻收藏。
您确实确实需要在开始和结束编写时准确记录日志,然后将其与该时间段内JVM中发生的STW暂停相关联,否则您真的不知道是什么引起了问题或问题的严重程度。
我会立即做的事情;
还有几件事要牢记…
CMS通常比其他收集器更喜欢堆,您的堆很小
在添加了问题的visualgc图形后进行编辑 由于您的内存有限,因此您需要充分利用自己拥有的空间,唯一的方法是通过反复进行基准测试(理想情况下使用可重复测试)。
您可以-Xmn用来指定设置年轻一代的大小,剩余部分将交给终身职位。
-XX:TargetSurvivorRatio=90
设置它,以便在复制之前需要将幸存者空间充满90%,显然在复制成本和使用空间之间需要进行权衡-XX:+PrintTenuringDistribution
显示每个空间的大小以及事物的状态,您也可以在visualgc
中看到它-XX:+MaxTenuringThreshold
指定一个对象在存留前可以在一个年轻集合中生存多少次(从1个生存空间复制到另一个生存空间),例如,如果您知道您只会得到短暂的垃圾或永久存在的东西,那么将其设置为1是明智的-XX:CMSInitiatingOccupancyFraction=<value>
,例如将其设置为80,它将以占用率80%的占用率触发CMS(注意:这是一件很容易出错的事情,因此,您可能宁愿让热点管理此问题;将其设置得太小且设置不正确收集频率过高会导致性能下降,将其设置得过大,可能触发得太晚,导致计划外的完整收集以及相应的暂停时间较长问题内容: 我正在制作一个Java应用程序,我需要播放音频。尽管我计划循环播放背景音乐,但我主要播放的是我的大炮射击(它是大炮射击游戏)和弹丸爆炸的小声音文件。我找到了两种不同的方法来实现此目的,但是两种方法都不符合我的要求。 第一种方法实际上是一种方法: 问题是我的整个程序停止运行,直到声音文件完成或至少接近完成。 第二种方法是这样的: 我这里的问题是,每次声音文件提早结束或根本不播放时,这取决
我试图为管道开发一个应用程序: gst-launch-1.0 rtspsrc位置=”rtsp://192.168.3.30:8554/rajvi“延迟=0 name=demux demux。!queue!rtpmp4gdepay!aacparse!avdec\u aac!audioconvert!audioresample!autoaudiosink demux。!queue!rtph264dep
我想以编程方式捕获内部音频。例如,我想(在我的设备上)播放一个音频文件,然后捕获音频输出,而不是在音量打开的情况下使用麦克风。 示例用例:我想制作一个其他开发者可以在游戏中使用的库,允许用户录制游戏中的音频。 Android说有回放捕获功能,但我只是找不到一个例子。我在谷歌上搜索了几个小时。每当我搜索“android捕获应用程序声音”或“androidrecordaudio”时,我要么会得到语音录
我试图写一个简单的应用程序,播放声音,可以改变音量的声音在任何时候播放。我通过将声音字节数组中的每对字节转换成一个整数,然后将这个整数乘以音量的增加或减少,然后将它们写回为两个字节(即1个样本)。然而,这导致了声音的极度失真。有没有可能我把位移错了?我的声音格式是: 这段代码的基础是:audio:改变字节数组中样本的音量,而asker正试图在其中执行相同的操作。然而,使用了他的问题中的代码(我认为
我一直无法让应用程序录制音频,同时让iPhone音乐应用程序通过蓝牙扬声器播放。 例如,如果我这样做: 然后音乐应用程序将开始通过iPhone内置的扬声器播放音乐,而不是通过蓝牙。换句话说,似乎没有办法在应用程序中录制音频的同时还允许通过蓝牙播放音乐。 如果我删除AVAudioSessionColloryOptionDefaultToSpeaker,那么音频路由将切换到接收器。这比让它通过iPho
问题内容: 如何使用Java将Wav文件转换为PNG波形图像文件? 预期成绩: 指定路径中保存的Png是传入的wav文件的波形。 问题答案: 下面是一个将执行此操作的java类。我在这里对某些参数进行了硬编码,例如图像的宽度,图像的高度,图像的背景颜色以及更多其他内容。如果您想将它们拉出来,可以。