9

どちらも大量のメモリを使用し、どちらもImageIO.write () を使用する 2 つの Java アプリケーションがあります。これまでのところ、この 2 つの共通点しか見つかりませんでした。

ループで画像のサイズを変更します。もう 1 つはイメージをループでダウンロードし、ディスクに保存します。関連するコードは次のとおりです。

1)

for(File imageFile : imageFilesList)
{
    if(!stillRunning) return;

    File outputFile = new File(imageFile.getAbsolutePath().replace(sourceBaseFolder.getAbsolutePath(), destinationFolder.getAbsolutePath()));
    try
    {
        outputFile.mkdirs();
        BufferedImage inputImage = ImageIO.read(imageFile);
        BufferedImage resizedImage = ImageResizer.resizeImage(inputImage, maxHeight, maxWidth);
        ImageIO.write(resizedImage, "jpg", outputFile);
    }
    catch(IOException ex)
    {
        userInterface.displayMessageToUser("IOException ocurred while converting an image: " + ex.getLocalizedMessage());
        System.out.println(outputFile.getAbsolutePath());
        ex.printStackTrace();
        return;
    }
    imagesConverted++;
    userInterface.updateTotalConvertedImages(++convertedFiles);
}

2) (ループ内)

try
{
    u = new URL(urlString);
    uc = u.openConnection();
    uc.addRequestProperty("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
    uc.connect();
    uc.getInputStream();
    in = uc.getInputStream();

    BufferedImage tempImage = ImageIO.read(in);

    String fileName = fn = ImageDownload.getFileName(u.getPath());
    fileName = outputDirString + FILE_SEPARATOR + fileName;
    while (new File(fileName).exists())
    {
        fileName = appendCopyIndicator(fileName);
    }

    ImageIO.write(tempImage, "jpg", new File(fileName));
    parent.notifyOfSuccessfulDownload(fn);
    in.close();
}
catch (FileNotFoundException ex)
{
    parent.notifyOfFailedDownload(fn);
}
catch (IOException ex)
{
    parent.handleException(ex);
}

どちらの場合も、プログラムは大量のメモリを使用します。RAMのギグの周り。また、ループが終了しても解放されません。どちらの場合も、swing gui を実行しています。画像の保存がすべて完了し、GUI がアイドル状態のときでも、プログラムはまだ 1Gb 以上のメモリを使用していることがあります。私は、swing gui によって直接使用されていないすべての変数をnullループの後に設定するところまで行きました。効果なし。

私は何が欠けていますか?

よろしくお願いします。

詳細: IDE (Netbeans) でアプリケーション 1 のプロファイルを作成しました。アプリケーション 1 を選択したのは、ImageIO のみを処理し (ネットワーク IO を処理しない)、より制御された実験だからです。

プログラムがその処理を実行している間 (ループ内の画像のサイズ変更)、合計メモリは約 900,000,000 ~ 1,000,000,000 バイトの間で推移しましたが、使用済みメモリは、特定の瞬間に使用されている合計メモリの約 30% から 50% の間で変動しました。

また、GC に費やされた時間は 1% を超えることはありませんでした。

実際のサイズ変更が終了し、プログラムが「アイドル」状態になるとすぐに、2 つのことが起こりました。1) 合計メモリが流動を停止し、1,044,054,016 バイトで静的なままになり、2) 使用メモリが ~14,000,000 バイト (14 mb) に低下しました。 .

したがって、JVM は、使用しなくなったメモリ スペースを返していないようです。

同意?それとも、この結果を誤解していますか?

4

4 に答える 4