0

こんにちは、java.swing.timer を使用する 1 つのアプリケーションがあり、これはループしています。問題は、私の Windows メモリ プロセスがまだ熱くなり、停止しないことです。System.gc() などを使用して変数をクリーンアップしようとしましたが、機能しません。これをスレッド、タイマースタック、スイングタイマーでテストするサンプルを作成しました。jcombobox 内に itens を追加しても、メモリはまだ増加しています。

コードは次のとおりです。

//マイタイマー

@Action
public void botao_click1() {
    jLabel1.setText("START");
    timer1 = new java.util.Timer();
    timer1.schedule(new TimerTask() {

        @Override
        public void run() {
            adicionarItens();
            limpar();
        }
    }, 100, 100);
}

@Action
public void botao_click2() {
    thread = new Thread(new Runnable() {

        public void run() {
            while (true) {
                adicionarItens();
                try {
                    Thread.sleep(100);
                    limpar();
                } catch (InterruptedException ex) {
                    Logger.getLogger(MemoriaTesteView.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    });
    thread.start();
}

private void limpar() { // CleanUp array and jcombobox

    texto = null;

    jComboBox1.removeAllItems();
    jComboBox1.setVisible(false);
    //jComboBox1 = null;

    System.gc();

}

private void adicionarItens() { //AddItens

    texto = new String[6];

    texto[0] = "HA";
    texto[1] = "HA";
    texto[2] = "HA";
    texto[3] = "HA";
    texto[4] = "HA";
    texto[5] = "HA";

    //jComboBox1 = new javax.swing.JComboBox();

    jComboBox1.setVisible(true);

    for (int i = 0; i < texto.length; i++) {
        jComboBox1.addItem(texto[i].toString());
    }

    System.out.println("System Memory: "
            + Runtime.getRuntime().freeMemory() + " bytes free!");

}

助けてください!!! =(

4

2 に答える 2

2

投稿したコードの小さな断片から、実際に問題が発生していることは明らかではありません。

いずれにせよ、あなたはあなたがコントロールしたいものをコントロールすることはできません

-XmxJavaヒープのみを制御し、JVMによるネイティブメモリの消費は制御しません。JVMは、実装に基づいてまったく異なる方法で消費されます。

次の記事からメモリをありがとう(JVMがWindowsおよびLinuxでネイティブメモリをどのように使用するかを理解する)

ヒープとガベージコレクターを維持するには、制御できないネイティブメモリを使用します。

Javaヒープを維持するメモリ管理システムの状態を維持するには、より多くのネイティブメモリが必要です。空きストレージを追跡し、ガベージを収集する際の進行状況を記録するには、データ構造を割り当てる必要があります。これらのデータ構造の正確なサイズと性質は実装によって異なりますが、多くはヒープのサイズに比例します。

JITコンパイラはネイティブメモリを使用しjavacます

バイトコードのコンパイルではネイティブメモリを使用しますが(gccなどの静的コンパイラが実行にメモリを必要とするのと同じ方法で)、JITからの入力(バイトコード)と出力(実行可能コード)の両方をネイティブメモリに格納する必要があります。多くのJITコンパイル済みメソッドを含むJavaアプリケーションは、小さなアプリケーションよりも多くのネイティブメモリを使用します。

次に、ネイティブメモリを使用するクラスローダーがあります

Javaアプリケーションは、オブジェクト構造とメソッドロジックを定義するクラスで構成されています。また、Javaランタイムクラスライブラリ(java.lang.Stringなど)のクラスを使用し、サードパーティのライブラリを使用する場合があります。これらのクラスは、使用されている限り、メモリに保存する必要があります。クラスの保存方法は、実装によって異なります。

スレッドに関するセクションの引用も開始し -Xmxません。自分が制御していると思うものを制御せず、JVMヒープを制御し、すべてがJVMヒープに入るわけではなく、ヒープがさらに多くを占めるという考えが得られると思います。管理および簿記のために指定するネイティブメモリ。

どこにも言及がありませんOutOfMemoryExceptions

あなたが心配していることは、とにかく直接ではなく、制御することはできません

あなたが焦点を当てるべきなのは、あなたが必要以上に参照を保持しないこと、そしてあなたが不必要に物事を複製していないことを確実にすることであるあなたのコントロールの中にあるものです。Javaのガベージコレクションルーチンは高度に最適化されており、それらのアルゴリズムがどのように機能するかを学ぶと、プログラムがそれらのアルゴリズムが機能するための最適な方法で動作することを確認できます。

Javaヒープメモリは、他の言語で手動で管理されるメモリとは異なり、これらのルールは適用されません

他の言語でメモリリークと見なされるものは、ガベージコレクションシステムを備えたJavaの場合と同じもの/根本的な原因ではありません。

ほとんどの場合、Javaメモリでは、リークしている単一のuberオブジェクトによって消費されていません(他の環境では参照がぶら下がっています)。

中間オブジェクトは、それらが含まれるスコープや実行時に変化する可能性のある他の多くのもののために、ガベージコレクターによって予想されるよりも長く保持される可能性があります。

例:ガベージコレクターは候補があると判断する場合がありますが、まだ十分なメモリがあると見なされるため、その時点でそれらをフラッシュするには時間的にコストがかかりすぎる可能性があり、メモリまで待機します圧力が高くなります。

ガベージコレクターは今では本当に良いですが、それは魔法ではありません。あなたが退化したことをしていると、それはそれが最適に機能しなくなる原因になります。インターネット上には、JVMのすべてのバージョンのガベージコレクター設定に関する多くのドキュメントがあります。

これらの参照されていないオブジェクトは、ガベージコレクターが、それらをメモリから消去するために必要であると考える時間に達していない可能性があります。または、他のオブジェクト(List)によって保持されているオブジェクトへの参照がある可能性があります。まだそのオブジェクトを指していることに気づきます。これは、Javaで最も一般的にリークと呼ばれるものであり、より具体的には参照リークです。

例:デフォルトではなくcreate itをString使用して4Kを構築する必要があることがわかっている場合は、32のように、オブジェクトのサイズを何倍も表すことができるガベージの作成をすぐに開始します。StringBuildernew StringBuilder(4096);

VisualVMでインスタンス化されているオブジェクトの種類の数を確認できます。これにより、知っておく必要のあることがわかります。「これは大きなメモリコンシューマーです!」という単一のクラスの単一のインスタンスを指す1つの大きな点滅ライトはありません。つまり、char[]大量のファイルを読んでいるインスタンスが1つしかない場合を除きます。他の多くのクラスがchar[]内部で使用するため、これも不可能です。そして、あなたはそれをすでにほとんど知っていました。

の言及はありませんOutOfMemoryError

コードに問題はないかもしれません。ガベージコレクションシステムは、クリーンアップする必要があると思われるオブジェクトを起動して割り当てを解除するのに十分なプレッシャーを受けていない可能性があります。プログラムがでクラッシュしない限り、問題だと思うのはおそらくそうではありませOutOfMemoryError。これは、C、C ++、Objective-C、またはその他の手動のメモリ管理言語/ランタイムではありません。何がメモリにあるか、またはあなたができるはずの詳細レベルで何がないかを決定することはできません。

于 2012-09-06T18:43:12.043 に答える
-1

理論的には、Javaは、Cベースの言語が持つ可能性のある種類の「リーク」の影響を受けません。しかし、意図したかどうかに関係なく、多かれ少なかれ無制限に成長するデータ構造を設計することは依然として非常に簡単です。

もちろん、タイマーベースのタスクなどをスケジュールする場合、それらへの参照を保持していなくても、時間が経過してタスクが完了する(またはキャンセルされる)まで、それらは存在します。

また、一部のJava環境(Androidはこれで有名です)は、通常のGCアクションの対象とならない方法でイメージなどを割り当て、ヒープを無制限に成長させる可能性があります。

于 2012-09-06T18:34:27.027 に答える