Reputation: 828
I am trying to run a sketch that is supposed to show images (png´s, between 100kb and 1,5mb in size, 55.4mb total) in a coverflow animation. it works with about 10 images, but using more I get a out of memory error. I am loading the images file names into an string array like so:
String[] names = {"00.jpg", "01.jpg", "02.jpg"};
and then they get loaded into the sketch like so:
covers = new Cover[names.length];
for (int i = 0; i < covers.length; i++ ) {
covers[i] = new Cover(names[i]);
}
initCovers();
covers class:
class Cover {
PImage img;
Cover( String name ) {
img = loadImage(name);
public void drawCover() {
beginShape();
textureMode(NORMALIZED);
texture(img);
vertex(-300, -300, 0, 0, 0);
vertex( 300, -300, 0, 1, 0);
vertex( 300, 300, 0, 1, 1);
vertex(-300, 300, 0, 0, 1);
endShape();
when I run the sketch, my ram (8gb) gets filled within seconds, and the sketch doesn´t even load, it just crashes. when I start the sketch with about 10 images, everything works fine ( bout 1,5gb of ram usage).
my question is: why is it using so much memory? is it normal? is there a way to make it run more memory efficient (e.g. freeup memory of images that are not currently displayed because we can only see about 3 images at once on screen).
EDIT: I think the problem is that in the cover class, each time it gets called a new PImage is created. could that be possible?
image size in memory: width * height * (color depth/8), so for my images (1575y1969, 24bit) that woul be 8,9mb. times 91 images: about 807mb of memory usage just for the images.
Upvotes: 2
Views: 2671
Reputation: 168815
Now that I understand the use-case better, I recommend to change the entire approach.
The types of applications (e.g. seen above) that you are trying to emulate do not load the entire slew of images as soon as the app. is presented. Instead, they read the small group of images that they are going to present to the user first. As the user approaches the end of that group, the software flushes some of the images at the start of the sequence (if memory is tight) and loads some more at the end.
Upvotes: 3
Reputation: 1788
The size of compressed images isn't a good guide to the memory requirements.
The size in pixels is better. For example a modern camera photo with 8 megapixel resolution requires at least 32mb of memory to represent. If you are manipulating images this size with swing, double or triple that, at least. It's easy to gobble up a lot of memory.
Also, Java's internal memory management isn't very good at dealing with chunks this size.
Upvotes: 1
Reputation: 514
I would say try painting them to a component using a single temp Cover as a handle as opposed to having N-many objects hanging around? And if you need interactions with images after draw time just hold back some simple meta data about their draw positions and dimensions, then use click event x,y etc to look up a a given image to allow you to work with it.
Upvotes: 0
Reputation: 347184
Try increasing the JVM heap space
java -Xmx1024m
(Yes, I know, 1gig is a 'little' excessive, but after some experimentation, this value can be trimmed down)
As @millimoose states, the images loaded by Java are uncompressed into memory when they are loaded, so even a small image of 100kb on disk can suddenly occupy mb's of RAM when uncompressed. It becomes even more complicated when you start dealing with the alpha channel as well.
Upvotes: 1