0

以下のコードでは、メモリ リークが発生します。

public static BufferedImage mergeImages2(BufferedImage base, Collection<Light> images) {
    BufferedImage output = new BufferedImage(base.getWidth(), base.getHeight(), BufferedImage.TYPE_INT_ARGB);

    Graphics2D g = output.createGraphics();
    g.drawImage(base, 0, 0, null);
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1.0f));
    for (Light l : images) {
        g.drawImage(l.LIGHT_IMAGE, l.x, l.y, null);
        l.LIGHT_IMAGE.flush();
    }
    g.dispose();
    output.flush();
    return output;
}

ここで読んだように: BufferedImage.getGraphics() でメモリ リークが発生しましたが、修正はありますか? .createGraphics() が問題です。

このコードは非常に頻繁に実行できます (タイマーは 50 ミリ秒の一定速度で動作するように設定されており、ライトが「動いている」場合はこのコードを呼び出しますが、ライトが同じ場所に留まっている場合はスキップされます)。正常に実行されますが、毎回プロセスのメモリが固くなります。これはカスケード プロセスであり、最終的に 180,000 K のメモリから 1 分未満で 600,000 K を超えるメモリに増加します。グラフィック的には、ある時点でクランクが(明らかに)過剰になり、FPSが大幅に低下するまでは正常に機能します.

これで、このブロックの呼び出しをコメント化すると問題が解消されるため、このブロックがリークを生成することがわかりました。

描画される基本画像は 1024x561 で、ライトの画像はかなり小さい (50x50) です。これまで、アレイ内のライトを 1 つだけ使用して常にテストしてきました。

メモリリークを回避するための解決策はありますか?

4

1 に答える 1

0

Andrew Thompson がコメントしたように、これは必ずしもメモリ リークではありません。ガベージ コレクターは、単純に思ったよりも遅く開始する可能性があります。通常、System.gc() の呼び出しは推奨されませんが、ライトが動いていないときに System.gc() の呼び出しを試すことができます。

または、BufferedImage の背後にある整数配列を直接操作するか (簡単ではありません)、別の API (JOGL など) を使用することもできます。

于 2012-11-27T13:03:03.060 に答える