0

私は Swing を使用しており、いくつかの JPanel を含む JFrame があり、そのうちの 1 つに JTextArea があります。

JTextArea コンテンツは、ユーザーが特定のメニュー ( ActionListener.actionPerformed(populate()) )をクリックすると設定されます。

コンテンツは 30MB のテキスト ファイルから取得されます。

private void populate () {
        StringBuilder strB = new StringBuilder();
        try {
            FileReader fr = new FileReader("file30mb.txt");
            BufferedReader br = new BufferedReader(fr);
            String strLine;

            while ((strLine = br.readLine()) != null) {
                strB.append(strLine).append(System.getProperty("line.separator"));
            }

            fr.close();
            br.close();
        } catch (IOException e) {
            System.err.println(e);
        }

        jTextArea1.setEditable(false);
        jTextArea1.setText(strB.toString());
        jTextArea1.setCaretPosition(0);
}

このプロセスは、約 200MB の大量のメモリを使用します。

別のメニューがあり、ユーザーがそれをクリックすると、JTextArea がクリアされます (基本的には、jTextArea1.setText(null)を実行するメソッドを呼び出します)。イベントは以前と同じ方法で処理されます: ActionListener.actionPerformed(free())

したがって、JTextArea が空の場合、メモリ使用量は以前よりも少なくなると思いますが、残念ながらそうではありません。タスク マネージャーに移動すると、以前と同じメモリ使用量 (約 200MB) が表示されますが、JTextArea は空です!

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

編集私もこれを試しました:

jTextArea1.setText(strB.toString());
jTextArea1.setText("");
Runtime r = Runtime.getRuntime();
r.gc();
System.out.println(jTextArea1.getDocument().getLength()); // prints "0"

しかし、それでも 200MB のメモリが必要です。

EDIT 2「GUI部分」(jTextArea1.setText()など)を削除しても、まだ多くのメモリが必要です。JTextArea には何も書き込まないため、「0 メモリ」を使用する必要がありますが、テキスト ファイルを読み取っただけで何もしません。私が間違っている?

4

1 に答える 1

3

いくつかの理由:

  • ガベージ コレクションは定期的に実行され、すぐにはメモリを解放しません。

  • JVM プロセス メモリとヒープ メモリの使用量は、2 つの異なるものです。詳細な GC ロギングを有効にするか、jconsole/を使用してアプリケーションに接続し、jvisualvm実際のヒープの使用状況を確認します。GC を手動で実行する

  • Ctrl+はZまだ機能しており、以前の (30 MB) のコンテンツを復元できますか? あなたはアイデアを得る...

これらのいずれも正しくない場合は、Eclipse MATなどのメモリ プロファイラーを使用して、この巨大なオブジェクトへの参照を保持しているものを見つけます (char[]サイズが 60 MB であることがわかります)。

于 2012-07-08T17:20:31.803 に答える