加载Podcast音频导致Java中的OutOfMemoryError

时间:2015-10-26 17:28:26

标签: java audio memory-leaks playframework

我有一个Java方法,可以为播客加载分块音频数据。据我所知,2或3个用户可以在播客中访问音频(通常大约40MB),然后我的应用程序内存不足并崩溃(java.lang.OutOfMemoryError:null)。我在Play框架中使用Java。

@With(MP3Headers.class)
public static Result getAudioByChunk(Integer audioId) {
    try {
        final Audio requestedAudio = Audio.findById.byId(audioId);
        int songLength = Files.readAllBytes(Paths.get(requestedAudio.filePath)).length;

        final int begin, end;
        final boolean isRangeReq;
        response().setHeader("Accept-Ranges", "bytes");
        if (request().hasHeader("RANGE")) {
            isRangeReq = true;
            String[] range = request().getHeader("RANGE").split("=")[1].split("-");
            begin = Integer.parseInt(range[0]);
            if (range.length > 1) {
                end = Integer.parseInt(range[1]);
            } else {
                end = songLength - 1;
            }
            response().setHeader("Content-Range", String.format("bytes %d-%d/%d", begin, end, songLength));
        } else {
            isRangeReq = false;
            begin = 0;
            end = songLength - 1;
        }

        Chunks<byte[]> chunks = new ByteChunks() {
            public void onReady(Chunks.Out<byte[]> out) {
                try {
                    if (isRangeReq) {
                        out.write(Arrays.copyOfRange(Files.readAllBytes(Paths.get(requestedAudio.filePath)), begin, end));
                    } else {
                        out.write(Files.readAllBytes(Paths.get(requestedAudio.filePath)));
                    }
                } catch (IOException ioe) {
                } finally {
                    out.close();
                }
            }
        };
        response().setHeader("Content-Length", (end - begin + 1) + "");
        if (isRangeReq) {
            return status(206, chunks);
        } else {
            return status(200, chunks);
        }
    } catch (Exception e) {
        return ok();
    }
}

我已经尝试过增加我的JVM内存(我只有一个GB的总内存可以在服务器上使用)。出于绝望,我试图在返回语句之后使'chunk'无效并在finally块中调用垃圾收集器。

我认为在将结果写入结果后,我错过了释放内存的命令,我到底错过了什么?

如果需要更多详细信息,请告知我们。

1 个答案:

答案 0 :(得分:0)

您可能需要使用流式传输模式,而不是将整个音频加载到内存中。

看看这个答案寻求帮助:

https://stackoverflow.com/a/32865159/5430900