4

ファイルを保存およびロードするJavaを使用したアプリケーションを作成しているため、ストリームを使用しています。ファイルからストリームを取得し、このストリームを使用して別のフォルダーに新しいファイルを作成します。問題は、ストリームを使用して閉じた後、解放されたはずのメモリがまだ残っていることです。

たとえば、100 mb のファイルをロードし (タスク マネージャーは、java.exe が 100 mb で増加していることを示しています)、そのファイルを別のフォルダーに保存し、stream.close() でストリームを閉じます。しかし、java.exe は 100MB 減りません。ファイルを数回保存してロードすると、java.exe が 600 MB を超えた後、300 MB に減少します。600MB を超えようとするたびに、300MB に減少します。どうしてこれなの?stream.close() を呼び出したときにメモリが 0mb にならないのはなぜですか? 約 600MB のメモリを解放し、すべてのメモリを解放しないのはなぜですか?

これは、文字列パスからストリームをロードしてストリームを閉じる方法です。

String path = ... //File path
InputStream stream = new BufferedInputStream(new FileInputStream(path));
stream.close();

返信ありがとうございます。

4

3 に答える 3

4

BufferedInputStream はデフォルトで 8 KB の固定サイズを使用するため、8 KB を超えてリークすることはありません (さらに少しのオーバーヘッド)。

100mb のファイルをロードします (タスク マネージャーは、java.exe が 100mb で増加することを示しています)。

これは、ファイルの処理に 100 MB のオブジェクトを使用していることを意味します。

しかし、java.exeは100MB減りません

そうすべき理由はありません。ほとんどの場合、GC の後に実行されますが、必要でない限り、それを実行したくはありません。

600MB を超えようとするたびに、300MB に減少します。どうしてこれなの?

ガベージのコレクションをトリガーしています。ほとんどの場合、マイナー コレクションです。

stream.close() を呼び出したときにメモリが 0mb にならないのはなぜですか?

開始したときは 0 MB ではありませんでした。GC を実行するとメモリが元に戻りますが、それを不必要に行いたくはありません。

約 600MB のメモリを解放し、すべてのメモリを解放しないのはなぜですか?

複数のメモリ領域があり、通常は eden スペースをクリーニングする、可能な限り単純な作業を実行しようとしました。

于 2012-09-26T16:53:25.790 に答える
2

表示されているのは、Java メモリ システムの通常の機能です。割り当てられたメモリは、必ずしも OS に返されるわけではありません。

OS レベルで java.exe のメモリをチェックする代わりに、組み込みのJConsoleツール (または、 より深い分析には無料のEclipse MAT ) などのメモリ アナライザーを使用する必要があります。

于 2012-09-26T16:51:59.830 に答える
-1

あなたのコードでは FileInputStream は匿名インスタンスです。

ファイルが大きいため、仮想メモリ/仮想 RAM に格納される場合があります。Javaがガベージコレクションを開始するまで、閉じません。

FileInputStream を新しい名前付きインスタンスとして作成し、閉じます

それはうまくいくはずです

于 2012-09-26T16:53:03.797 に答える