0

基本的にツリーである恐ろしいデータ構造で遊んでおり、各ノードはその子への参照をHashMapオブジェクトに格納しています。この後者のサブツリーを新しいルートとして設定することにより、ルートとそのすべてのサブツリーを削除する必要があるときはいつでも、メモリを解放するのに問題があります。データ構造のバグかもしれないと思ったのですが、そこにいるのを忘れていた参照かもしれないので、何もガベージコレクションの対象になりません。しかし、最初にもっと単純なことを試してみたかったので、次のテストを実装しました。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class MyNode {
        MyNode next;
        int somedata;

        public MyNode(MyNode n) {
            next = n;
            somedata = 0;
        }

        public static void main(String[] args) throws IOException {
            MyNode p = new MyNode(null);
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            for (int i=0; i<10000000; i++) {
                MyNode n = new MyNode(p);
                p = n;
            }
            while (p!=null) {
                MyNode p1 = p.next;
                p.next = null;
                p = p1;
            }
            in.readLine();
        }
}

main に到達するin.readline()と、htop を見ると、プロセスにはまだ 250MB 程度が割り当てられており、何も解放されていないことがわかります。私は明らかに最初に単純にやろうとしました

p = null;

while ループの代わりに。しかし、うまくいかなかったので、前のコードを思いつきました。

4

4 に答える 4

1

あなたの質問はやや不明確です - あなたは実際に OutOfMemoryErrors を得ていますか? 何を解決しようとしていますか? テスト ケースで動作が明らかになったのには、いくつかの理由があります。

  1. 何かが GC ルートから到達できなくなった時点では、ガベージは収集されません。ガベージ コレクションの対象になるだけです。GC は通常、割り当てに失敗した場合にのみトリガーされます。実際には、参照を無効にするループ内でこれ以上メモリを割り当てていないため、GC がまだ実行されていない可能性は十分にあります。

  2. ガベージが収集された場合でも、通常、ヒープ内のメモリは OS に返されないため、OS の観点から見ても正確な答えは得られません。VisualVM または jmap や jhat などのツールを使用することは、実際にまだヒープ上にあるものを把握するための最良の方法です。

于 2012-07-28T21:25:03.397 に答える
0

ガベージ コレクタの動作は複雑で、異なるガベージ コレクタは根本的に異なるメソッドを使用できます。ガベージを明示的に呼び出したとしても、ガベージがすぐに回収されるとは期待できません。

于 2012-07-28T21:10:40.693 に答える
0

これは前に見たことがあります。

htop は、JVM によるメモリ使用率を測定する最良の方法ではありません。高い成績を残し続けています。VM は、ヒープの割り当てを可能な限り高く保つことも好みます。

Visualgc または jconsole を使用して追跡するか、JVM に同梱されている jps および jpstat を使用することをお勧めします。 http://java.sun.com/performance/jvmstat/#Tools

また、多くのオブジェクトをすばやく作成するループがあるため、gc を起動する時間がある可能性があります。System.gc が実際に実行されるとは限りません。ヒントですが、通常は動作します。

Java ヒープの使用率に関するこの投稿もご覧ください: http://it.toolbox.com/blogs/lim/how-to-get-details-on-jvms-heap-utilization-10609

于 2012-07-28T21:22:04.413 に答える
-4

コードを使用して、10000 ループで 1 回、ガベージ コレクションを手動で呼び出すことができます。

System.gc();

ただし、ガベージ コレクターによって使用される余分な CPU 時間など、いくつかの副作用があります。

于 2012-07-28T21:00:30.410 に答える