どちらも大量のメモリを使用し、どちらも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 は、使用しなくなったメモリ スペースを返していないようです。
同意?それとも、この結果を誤解していますか?