gpt4 book ai didi

java - 减少垃圾收集时间

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:49:25 26 4
gpt4 key购买 nike

我正在申请一次播放 30 个视频。我正在使用 Xuggler 解码视频文件并使用 Swing 窗口进行显示。

但是我面临着这样的问题:

  1. 视频显示不流畅
  2. 我发现使用 profiler,大约 25% 的时间花在了垃圾收集上。

我应该如何调整垃圾收集器以及其他哪些性能参数?

Xuggler-Java组合不好吗?

编辑

我的视频解码循环是:

private boolean decodeStreams() throws Exception {
IPacket packet = IPacket.make();

long firstTimestampInStream = Global.NO_PTS;
long systemClockStartTime = 0;

viewer.urlStatusUpdate(index, Globals.STATUS_PLAYING);

while (container.readNextPacket(packet) >= 0) {
if (stopPlaying) {
if (isStopPlaying(2)) {
return false;
}
}

if (packet.getStreamIndex() == videoStreamID) {
IVideoPicture picture = IVideoPicture.make(videoCoder.getPixelType(), videoCoder.getWidth(), videoCoder.getHeight());
int offset = 0;
while (offset < packet.getSize()) {
int bytesDecoded = videoCoder.decodeVideo(picture, packet, offset);
if (bytesDecoded < 0) {
throw new Exception("Got error on decoding video");
}
offset += bytesDecoded;
if (picture.isComplete()) {
if (firstTimestampInStream == Global.NO_PTS) {
firstTimestampInStream = picture.getTimeStamp();
systemClockStartTime = System.currentTimeMillis();
} else {
long millisecondsToSleep = (
((picture.getTimeStamp() - firstTimestampInStream) / 1000)
- (System.currentTimeMillis() - systemClockStartTime)
);
if (millisecondsToSleep > 50) {
try {
Thread.sleep(millisecondsToSleep - 50);
} catch (Exception e) {
}
}
}
viewer.videoImageUpdate(index, converter.toImage(picture));
}
}
}
}

return true;
}

并且我更改了 IVideoPicture 声明的位置:

private boolean decodeStreams() throws Exception {
IPacket packet = IPacket.make();

long firstTimestampInStream = Global.NO_PTS;
long systemClockStartTime = 0;

viewer.urlStatusUpdate(index, Globals.STATUS_PLAYING);
IVideoPicture picture = IVideoPicture.make(videoCoder.getPixelType(), videoCoder.getWidth(), videoCoder.getHeight());

while (container.readNextPacket(packet) >= 0) {
if (stopPlaying) {
if (isStopPlaying(2)) {
return false;
}
}

if (packet.getStreamIndex() == videoStreamID) {
int offset = 0;
while (offset < packet.getSize()) {
int bytesDecoded = videoCoder.decodeVideo(picture, packet, offset);
if (bytesDecoded < 0) {
throw new Exception("Got error on decoding video");
}
offset += bytesDecoded;
if (picture.isComplete()) {
if (firstTimestampInStream == Global.NO_PTS) {
firstTimestampInStream = picture.getTimeStamp();
systemClockStartTime = System.currentTimeMillis();
} else {
long millisecondsToSleep = (
((picture.getTimeStamp() - firstTimestampInStream) / 1000)
- (System.currentTimeMillis() - systemClockStartTime)
);
if (millisecondsToSleep > 50) {
try {
Thread.sleep(millisecondsToSleep - 50);
} catch (Exception e) {
}
}
}
viewer.videoImageUpdate(index, converter.toImage(picture));
}
}
}
}

return true;
}

现在 GC 花费的时间不到 10%,正常情况下约为 5% 到 8%。而且我一次可以流畅地播放所有 30 个视频。

改变位置(将 IVideoPicture 声明放在外面,并且只分配一次内存)会是问题吗?每次在分配的内存上解码新视频图片时,图片的时间戳是否设置?

谢谢

最佳答案

很可能您当前的 GC 不适合您的任务。要获得可预测的 GC 计时,您可以尝试使用 G1 垃圾收集器(我假设您使用的是 Java 7u4 或更高版本)。G1 计划作为并发标记-清除收集器 (CMS) 的长期替代品。将 G1 与 CMS 进行比较,有一些差异使 G1 成为更好的解决方案。 G1 提供比 CMS 收集器更可预测的垃圾收集暂停,并允许用户指定所需的暂停目标。

使用以下选项为您的特定情况存档最佳性能:

-XX:+UseG1GC - 告诉 JVM 使用 G1 垃圾收集器。

-XX:MaxGCPauseMillis=500 - 设置最长 GC 暂停时间的目标。这是一个软目标,JVM 将尽最大努力实现它。因此,有时达不到暂停时间目标。默认值为 200 毫秒。

-XX:InitiatingHeapOccupancyPercent=80 - 启动并发 GC 周期的堆占用百分比。 G1 使用它根据整个堆的占用情况触发并发 GC 周期,而不仅仅是其中一个代。值为 0 表示“执行恒定的 GC 循环”。默认值为 45%。

提供更多详细信息 here

关于java - 减少垃圾收集时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17906775/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com