Bug 1542 : OpenGL mode leaking memory
Last modified: 2010-06-05 03:52




Status:
RESOLVED
Resolution:
WONTFIX -
Priority:
P2
Severity:
normal

 

Reporter:
Imran
Assigned To:
fry

Attachment Type Created Size Actions
screenshot of taskmanager and OutOfMemoryError image/png 2010-04-14 19:38 77.09 KB
suburb.pde application/octet-stream 2010-04-14 20:34 323 bytes
PFeature.pde application/octet-stream 2010-04-14 20:36 809 bytes
shapeplot.pde application/octet-stream 2010-04-14 20:40 7.50 KB
shapefile for testing application/octet-stream 2010-04-14 20:43 43.13 KB

Description:   Opened: 2010-04-13 01:08
Leaky behaviour confirmed on both Windows XP and Linux. On both occasions
test was done with Processing-183.

Windows (desktop) machine with ATI gpu.
Linux (laptop) machine with Nvidia gpu.

Observation:
For the example program below, the memory usage (as per Windows Task
Manager) is stable around 24KB. Once the size() call is modified to use
OPENGL, for the very same program memory can be seen increasing every
second. The exact same behaviour is replicated on a Linux machine when
OPENGL mode is used.

The increase per second is quite low (about 4KB per second), but for a
non-trivial program it is much larger. Displaying even a simple ESRI
shapefile (~160KB in size), leads to an increase of about 1MB per second!
For larger shapefiles, the increase is larger.

When in non-OPENGL mode(P2D), the memory usage seems to oscillate around a
median value; perhaps due to the garbage collector kicking in for
intermediate temp objects. With OPENGL mode, the memory usage constantly
increases with no visible decrease.

//Program demonstrating opengl mem leak
//modify the size() call watch the memory leak appear/disappear
import processing.opengl.*;

int num_circles = 200;
float[] x;
float[] y;
float[] sz;
int[] col;

void setup()
{
size(400,400);//,OPENGL);
x = new float[num_circles];
y = new float[num_circles];
sz = new float[num_circles];
col = new int[num_circles];

for(int i=0; i<num_circles; i++)
{
x[i] = random(0,width-1);
y[i] = random(0,height-1);
sz[i] = 80 + random(-40,40);
col[i] = int(random(20,250));
}
noStroke();
}

void draw()
{
background(0);
for(int i=0; i<num_circles; i++)
{
fill(col[i]);
ellipse(x[i],y[i],sz[i],sz[i]);
}
}

Ofcourse there are more complicated and even simpler programs to
demonstrate this issue; but the above will suffice for now.

My thoughts:
Since the leak is platform independent, I can only think that some OpenGL
buffer or something similar to it is being kept around through the loops of
the draw() method.
Additional Comment #1 From fry 2010-04-13 03:43
Does the application run out of memory?

How much additional memory is being used?

Does the same thing happen with other shapes besides ellipse?
Additional Comment #2 From Imran 2010-04-13 05:41
I let a shapefile with
low no. of features : 8
medium no. of points per feature : total file size about 160KB
run for a while.

As I said in the post earlier, it was eating about 1MB per second. I let it
run and it ate 500MB as per Windows Task Manager. Memory was still growing
and windows started swapping out applications to virtual mem. Everything
started crawling after this until I stopped the app.

So, it did not run out of memory. The desktop machine had 1GB RAM and about
1.5GB swap. If you want me to really test it, tomorrow I will let it run
until it eats up all the available memory and reports OutofMemory.
Additional Comment #3 From Imran 2010-04-13 05:43
Forgot to mention about other shapes.

Yes, the same thing happens with *anything* that is drawn using the OPENGL
mode. Either this is something recent or something that hasn't been noticed
at all. I will try a simple test and report back soon.
Additional Comment #4 From fry 2010-04-13 07:58
k, the example there doesn't seem to have much trouble (or at least it's
not very evident) on the osx machine i'm using now. i suspect that it may
be a different issue with the shapefiles--that there might be a problem
with PShape not being efficient (or whatever you're using for the shapefile
code), rather than the renderer.
Additional Comment #5 From Imran 2010-04-13 19:42
Instead of running my shapefile test, I let a much simpler test run for a
reasonably long time.

import processing.opengl.*;

void setup()
{
size(400,400,OPENGL);

noStroke();
rectMode(CENTER);
fill(250);
}

void draw()
{
background(127);
rect(width/2,height/2,width-100,height-100);
}

I let this one run for 2 hours(or close to it). Memory usage is 77MB and
rising. It seems to rise at a constant rate of about 4KB per second.. so
I'm not entirely sure about the total time it has been running.

Oh and your comment about PShape or my shapefile code being the problem is
not correct. On the exact same code, simply switching to the default
renderer(P2D?) make the memory usage peak and oscillate very slightly.
Similar behaviour for the above code.

I'm not entirely sure this is a Processing memleak and there isn't a
simpler example I can provide for this.
Additional Comment #6 From fry 2010-04-14 03:22
The problem is that with the way the JVM works, using 77 MB after two hours
is not necessarily an error. A library (in this case, the JOGL classes from
Sun) or something else may be doing some additional memory allocation
that's out of our control, but it's not necessarily a leak, it's just that
the JVM hasn't bothered to do garbage collection, because it doesn't need
to. It's not like a C/C++ program where things are more cut and dried, and
increasing memory usage = a leak. Unless it causes an OutOfMemoryError
after some time, then I don't have any way of knowing whether it's actually
a bug or something fixable.
Additional Comment #7 From Imran 2010-04-14 19:01
Yes, that makes sense. Which is why I am now letting a version of the
shapefile displaying code run. I will let it run until I see an OutOfMemory
or machine crash.

Will report back in 2 or so hours.
Additional Comment #8 From Imran 2010-04-14 19:38
edit]
screenshot of taskmanager and OutOfMemoryError

Wow, I didn;t have to wait very long.

Please see screenshot showing OutOfMemoryError and the Windows XP dialog
showing that the app was terminated. Please note that the memory shown for the
first entry in the Windows Task Manager is "low" because most of it has been
swapped to virtual mem.

This behaviour is not seen from the exact same sketch, but in default(P2D)
mode. I had this sketch running on P2D for hours yesterday to see if I get a
remotely similar memory behaviour.

Now, I am pretty convinced that there is a memleak somewhere
(jogl/processing/other).
Additional Comment #9 From fry 2010-04-14 19:46
thanks, can you provide a sketch that shows the problem so i can debug
what's going on?
Additional Comment #10 From Imran 2010-04-14 20:32
I will provide the shapefile display sketch that shows the problem, but it
uses the java bindings for the gdal library @ http://gdal.org

As per http://trac.osgeo.org/gdal/wiki/DownloadingGdalBinaries, there are
some binary distributions available. OSX versions available at
http://www.kyngchaos.com/software:frameworks. I am uncertain about the OSX
versions, but the Windows binaries from http://vbkto.dyndns.org/sdk/ most
certainly contain the java bindings. I simply needed to copy the dlls and
the gdal.jar file into the 'code' dir within the sketch.

On Linux, it is much simpler I simply need to set LD_LIBRARY_PATH and make
sure the gdal.jar is in the CLASSPATH before starting processing.

I really hope I have done something embarrasing and there isn't a bug here.
Additional Comment #11 From Imran 2010-04-14 20:34
edit]
suburb.pde

suburb class, not strictly necessary but I include it anyway.

Note: you need the below 2 files also
Additional Comment #12 From Imran 2010-04-14 20:36
edit]
PFeature.pde

PFeature class.

Note: you need both the above and below files along with this.
Additional Comment #13 From Imran 2010-04-14 20:40
edit]
shapeplot.pde

shapeplot sketch that demonstrates the possible memleak

Note: you need the above 2 files along with this one.
Additional Comment #14 From Imran 2010-04-14 20:43
edit]
shapefile for testing

Forgot to mention that you need a shapefile to test. Something small and
reasonable like this attached file will do.
Additional Comment #15 From Imran 2010-04-14 21:09
Ok, my brother asked me to add

System.gc();

as the last statement in draw(). Although he told me that it is not
guaranteed to call the garbage collector, it definitely is doing something.
Mem usage seems to stay stable at about 56MB for the shapeplot sketch. I'm
not sure if this is the 'solution' or I was doing something wrong or there
is some kind of pesudo-bug within the opengl rendering code, etc.
Additional Comment #16 From fry 2010-04-21 14:54
if it's something fixed by System.gc(), it's not likely anything that can
be done on our end. You should never have to call System.gc(), but it if
doing so changes anything, it suggests that other threads are preventing
the garbage collector thread from running. This might be just that your
application doesn't have any sleep time in it, since you're rendering
complex geometry, but I can't find anything in the situation that would
suggest that it's a Processing bug that I can fix.