We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi all, I need to display many PImages simultaneously on the screen. The original image files are big and I resize the PImages when loaded. After 2 minutes I need to load and display other many PImages. Which is the right way to dispose a PImage and release its memory? Because after more or less 1 hour I get OutOfMemoryException. This is my simplified code:
List<PImage> images = new ArrayList<PImage>();
void setup()
{
size(displayWidth, 200, OPENGL);
loadImages(dataPath("mediagallery"));
}
void draw()
{
background(0);
float x = 0;
for (PImage img : images)
{
image(img, x, 0);
x += img.width;
}
}
void loadImages(String path)
{
images.clear();
File dir = new File(path);
for (File file : dir.listFiles())
{
PImage img = loadImage(file.getPath());
img.resize(0, height);
images.add(img);
}
}
void keyPressed()
{
if (key == ' ') loadImages(dataPath("mediagallery"));
}
In Processing 1.5.1 PImage has the delete() method. There's something similar? Thanks!
Answers
Hey Paulo,
When I moved to P2, and it was still in beta, I came across a similar issue. After many hours on VisualVM (not sure if that was the profiling tool I used) I discovered that whenever I did a loadImage, processing would create a texture behind the scenes and that was not being released causing the images to stay in memory. I don't really remember how I worked around this, but forcing a garbage collection can be a good start:
loadImages(String path) { images.clear(); System.gc(); ...
Hi, using VisualVM you can see Java Heap Memory. This goes down forcing the garbage collector. The problem is that the memory used by the process (you can see it with Activity Monitor on MAC OSX) still remains big. What I tried is:
As you discovered this is the texture not released. This code improve the situation but don't solve the memory issue.
Processing's PGraphics will try to setCache() any PImage into a WeakHashMap when we draw it via image()!
When you clear() your List, sooner or later those PImage references got removed from that WeakHashMap too.
However, that'll only happen if there's no other fields or data containers storing references for them! :-@
The most correct procedure is bug-hunt your code for any possible extra hanging PImage references!
The other option is manually removing all WeakHashMap's cache entries via removeCache().
An even lazier fix is simply display PImage objects via set() in place of image(). :-j
However, you'd lose any alpha and transformations by doing so.
But if you don't use any fancy effects, you should definitely use set()! It's faster too! $-)
Hi GoToLoop, I'm trying to follow your suggestions, bug-hunt and manually removing cache calling removeCache(). I cannot use set() to display PImages because I'm using alpha. Because of I have to display a lot of images I thought to use a PGraphics to draw them, and then call the image() function passing the same PGraphics, like this:
It is ok to use PGraphics in this case? And if I want to release it's memory can I call simply removeCache(offscreen)? And how I can release PImages passed through the method offscreen.image()? Thanks in advance
At the very least you would need to
You would have to change draw to
As an alternative to setting offscreen to null you could use the reference to create a new PGraphics e.g.
Sure, this is what I do. I call manually removeCache() when I need and I remove all PImage references, I pass all my code many times, but I still have OutOfMemory exception:
I still think that the problem is the memory allocated with the Texture class, that is never (o almost never) released. Is is possible to force it?
I've included your anti-Texture disposeSourceBuffer() method in my example now!
Dunno whether it makes any difference though! :-/
I think not, the problem persists. My finally solution is to use Processing 1.5.1 with GLGraphics library, that offers better performance with images and memory.
Old Processing 1.5.1 is the last version which provided deployment as a packaged ".jar" file for 3 OSes!
And b/c it uses an older OpenGL version, it is more compatible w/ more systems!
If we can still manage to write compatible code for that venerable version, it is a better choice indeed! :-bd
I'm having some troubles with GLGraphics / OpenGL, my textures have fuzzy borders. Is it possible to increase their borders smooth? Using some parameters like:
gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)
maybe related: when using image(img, 0,0) over an offscreen renderer, img appears modified afterwards. I mean, the frame img was carrying before been used on myPGraphics.image(img, 0,0); is not the same after. why this could be happening? thnks
in processing 2.2.1