0

私はJava でKoch フラクタル スノーフレークを実行しており、それを svg ファイルに保存しています。

LineStrip2Dクラスでフラクタルを暗記してやっています(イテラブルを実装したVec2DのArrayListのラッパーです)。

主な機能は次のとおりです。

public static LineStrip2D repeatPatternIntoLineStrip2D(
        LineStrip2D pattern,
        LineStrip2D polygon, 
        boolean repeatUp) {

    /*
     * pattern: must be a pattern between Vec(0,0) and Vec(1,0)
     *          (normalized beetween 0-1 and in X axis)
     * */

    float angle, distance;
    Vec2D pivot, a, b, direction, b1;
    LineStrip2D new_polygon = new LineStrip2D();

    new_polygon.add(pattern.vertices.get(0));
    a = polygon.vertices.get(0);

    int count=0;
    for (int i = 1; i < polygon.vertices.size(); i++) {
        b = polygon.vertices.get(i);
        a = polygon.vertices.get(i-1);

        distance = b.distanceTo(a);
        direction = b.sub(a).normalize();
        angle = PApplet.atan2(direction.y, direction.x);
        pivot = a;

        for (int j = 1; j < pattern.vertices.size(); j++) {
            Vec2D _b1 = pattern.vertices.get(j);

            b1 =  _b1.copy() ;

            if(repeatUp)b1.y *= -1;             
            b1.scaleSelf(distance);
            b1 = b1.rotate(angle);
            b1.addSelf(pivot);

            new_polygon.add(b1);
            count++;
        }
        a = b;
    }
    System.out.println(count);
    return new_polygon;
}

初期コッホ曲線のパターンがあります:

ここに画像の説明を入力

そして私は電話します:

pattern = GeometryHelper.repeatPatternIntoLineStrip2D(pattern, pattern, false);

今問題:

いくつかの反復 (851968) の後、java.lang.OutOfMemoryError: Java heap spaceが発生しました。このエラーを回避し、巨大な svg ファイルを作成するにはどうすればよいですか? このプロセスはさまざまなステップで実行できると思いますが、スマートな方法で実装する方法がわかりません。

4

4 に答える 4

3

まず最も簡単なのは、JVM により多くのメモリを与えることです。-Xmx=1g を追加するだけで十分かもしれません (最近のほとんどのマシンで動作します)。さらに必要な場合は、お使いのマシンで利用できる容量を超えるまで、自由に追加してください。

そうは言っても、フラクタルを扱うと、常にメモリ使用量の上限があります。最初に、アプリケーションをプロファイリングして、すべてのメモリがどこで使用されているかを確認する必要があります。それが見つかったら、問題を再処理して、もう少しメモリに優しいものにすることを検討できます。または、前の反復からメモリを節約するために、反復の間に結果を反復してディスクに保持する設計に移行することもできます。

于 2012-01-03T20:47:23.110 に答える
2

他の人が述べたように、最初のステップは、JVMヒープサイズを変更するだけで必要な反復回数を達成できるかどうかを確認することです(これはコマンドラインパラメーター-Xmx=...です。ここで...は最大値です。割り当てたいメモリサイズ)。マシンに十分なRAMがある場合は、これをかなり高く設定できます(JVMにディスクスワップスペースを使用させる方法があるため、めちゃくちゃ高くなる可能性がありますが、これが可能かどうかはわかりません。 )。

それが不十分な場合は、反復(非再帰)実装で使用する独自のスタックを管理し、ディスクにシリアル化する必要があります。これは、スタックを引数として関数に渡し、関数がそのパラメーターをスタックから読み取り(スタックに残して)、ループする前にパラメーターをスタックに書き込む(および必要な最大深度に達すると、スタックからデータをポップし始めます)。スタックのシリアル化/永続性(サイズが大きくなるにつれてパーツをディスクに格納するためにそれ自体を管理する必要がある)と同様に、反復的な実装とスタック管理は重要です。

于 2012-01-03T21:09:08.180 に答える
1

この問題は、ArrayList をカプセル化する LineStrip2D クラスに関連していると思います。その List 実装は、サイズが直線的に増加する Array によってバックエンドになっています (ここで述べたようにArrayList: how does the size increase? )。ArrayList は古い配列を保持しながら、新しいサイズの完全な新しい配列を割り当てるため、メモリが不足していると思います ( http://en.wikipedia.org/wiki/Dynamic_array )。したがって、図面を完成させるには、少なくとも 2*MAX_SIZE が必要です。合計ヒープを増やす必要がありますが、LinkedList に切り替えると状況が改善されるはずです。

于 2012-10-21T10:53:33.913 に答える
0

まず、なぜ変数を使用しているのですcountか? 理由もなくSystem.out.println(polygon.vertices.size() * polygon.vertices.size());、無駄なインクリメント操作に置き換えて削除することができます。count

メモリ不足エラーについては、VM のヒープ サイズを増やしてみてください

于 2012-01-03T20:38:36.387 に答える