2012-01-03 14 views
0

私はKoch fractal snowflakeをJavaで実行していて、それをsvgファイルに保存しています。フラクタルと "java.lang.OutOfMemoryError:Java heap space"

私はLineStrip2Dクラス(iterableを実装する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; 
} 

私は、最初のコッホ曲線のパターンがあります。

enter image description here

をと私は呼ん:今すぐ

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

問題:

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

答えて

0

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

、あなたのVM

+0

私は、1つの変数を削除するとヒープサイズの問題が解決されるとは思えません。 –

+1

私はちょうど彼が彼のコードでいくつかの役に立たない操作を持っているという事実を指摘しています –

+0

@ Jason482:+ 1に対抗する+1:答えは正しい、有用かもしれない追加情報を含んでいて、答え(他のものより少し細かくはあるが)。 downvote、IMHOの価値がない。 – Mac

3

まずのヒープサイズを大きくしようとすると、最も簡単には、JVMに多くのメモリを与えることです。 -Xmx = 1gを追加すれば十分でしょう(そして、今日のほとんどのマシンで動作します)。あなたのマシンで利用可能なものを上回るまで、さらに必要があればさらに追加してください。

言われているように、フラクタルを扱うと、常にメモリ使用量の上限があります。最初に、アプリケーションのプロファイルを作成して、すべてのメモリが使用されている場所を確認する必要があります。一度それを見つけたら、もう少しメモリに優しい問題を再検討することができます。または、反復の間にディスクに結果を反復して持続させるデザインに移行して、以前の反復からメモリを節約することができます。

2

他にも言及したように、最初のステップは、JVMヒープサイズを変更するだけで反復回数を達成できるかどうかを試してみることです(コマンドラインパラメータ-Xmx = ... where.. ..)。 。は割り当てたい最大メモリサイズです)。あなたのマシンに十分なRAMがあるなら、これをかなり高く設定することができます(そして、おそらくJVMにディスクスワップスペースを使用させる方法があるので、非常に高くなる可能性がありますが、 )。

これが不十分な場合は、反復(非再帰的)実装で使用する独自のスタックをディスクに管理してシリアル化する必要があります。これはどのように見えるかは、引数としてスタックに渡し、関数はスタックからパラメータを読み込み(スタック上に残す)、スタックにパラメータを書き込んでからループします。最大限の深さに達すると、スタックからデータをポップすることができます)。反復実装とスタック管理は、スタックのシリアライゼーション/パーシスタンス(サイズが大きくなるにつれてディスクにパーツを格納するために自身を管理する必要がある)と同様に、自明ではありません。

+0

スタック上のシリアライゼーションの実装方法の説明はありますか? – nkint

+0

私はこのプロジェクトをやり直しています。これは私が実装できる最良の解決策です。しかし、私は完全にそれを理解していない..さらなる説明や例を得るための方法はありませんか? – nkint

+0

@nkintヒープサイズは現在どのように設定していますか?あなたのマシンでどれくらいのRAMを利用できますか? –

1

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

関連する問題