0

I am doing Koch fractal snowflake in java and save it in a svg file.

I am doing it memorizing the fractal with a LineStrip2D class (it is a wrapper of ArrayList of Vec2D that implements iterable).

The main function is this one:

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;
}

I have a pattern with initial koch curve:

enter image description here

And I call:

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

Now the problem:

After some iterations (851968) I have a java.lang.OutOfMemoryError: Java heap space. How can I avoid this error and achieve a huge svg file? I think I can do this process in various steps, but I don't understand how to implement it in a smart way.

javanna
  • 59,145
  • 14
  • 144
  • 125
nkint
  • 11,513
  • 31
  • 103
  • 174

4 Answers4

3

First and easiest is to give the JVM more memory. Adding -Xmx=1g may be enough (and would work on most machines nowadays). Feel free to add more if you need more, up until it exceeds what's available in your machine.

That being said, dealing with fractals there will ALWAYS be an upper limit you hit with memory usage. First you should profile your application to see where all the memory is being used. Once you find that, then you can consider re-working the problem to be a bit more memory friendly. Or, you could shift to a design that iterates and persists results to disk in between iterations to save memory from previous iterations.

rfeak
  • 8,124
  • 29
  • 28
2

As other have mentioned, the first step is to try and see if you can achieve the number of iterations you want just by modifying the JVM heap size (it is the command line parameter -Xmx=... where ... is the maximum memory size you wish to allocate). If you have enough RAM on your machine then you could set this pretty high (and maybe there is a way to get the JVM to use disk swap space, so it could be insanely high, but I do not know how / if this is possible).

If that is inadequate, then you will need to manage and serialize to disk your own stack that you use in an iterative (non-recursive) implementation. How this would look is that you would pass a stack to your function as an argument, and the function would read its parameters off of the stack (leaving them on the stack), and then write parameters to the stack before looping over itself (and as you reach your maximum desired depth you then begin popping data off of the stack). The iterative implementation and stack management are non-trivial, as is the serialization / persistence of the stack (which would need to manage itself to store parts to disk as it increased in size).

Trevor Freeman
  • 7,112
  • 2
  • 21
  • 40
  • where can i find some explanation of how implement a serialization on a stack? – nkint May 30 '12 at 16:18
  • i'm on this project again and this seems the best solution i can implement. but i haven't understood it completly.. no way to get further explanation or example? – nkint Oct 20 '12 at 17:01
  • @nkint What have you set your heap size to now? How much RAM do you have available on your machine? – Trevor Freeman Oct 23 '12 at 18:42
1

I believe the problem is related to the LineStrip2D class incapsulating an ArrayList: that List implementation is backend by an Array, which size grows linearly (as stated here ArrayList: how does the size increase?). I believe you run out of memory because ArrayList allocate a full new array with that new size, while preserving the old one (http://en.wikipedia.org/wiki/Dynamic_array). So to complete your drawing you need at least 2*MAX_SIZE. You should increase the total heap, but switching to a LinkedList should improve the situation.

Community
  • 1
  • 1
Matteo Collina
  • 1,469
  • 1
  • 8
  • 4
0

First of all why are you using the variable count? You could replace it with System.out.println(polygon.vertices.size() * polygon.vertices.size()); and remove a useless operation of incrementing count for no reason.

For your out of memory error, try increasing the heap size of your VM

Adel Boutros
  • 10,205
  • 7
  • 55
  • 89