It's my first time writting there but after reading and searching a lot about the subject I'm going to explain, I didn't found anything useful for me (I've checked a post of a guy explaining something similar about an iphone app, but without a final solution). Sorry for my english I'll try to do my best hehe :).
Ok, I'm starting: I have java application that shows a set of animations at the same time on a JPanel. These animations are java objects from Animation (inheritates from JLabel), a class of my own that stores an array of ImageIcon (representing the frames of animation) and an integer pointer, showing actual frame to paint (index). That class has overriden the method setPaint() in that way:
@Override
public void paintComponent(Graphics g) {
g.drawImage(getImageAt(getCurrentIndex()).getImage(), getX2(), getY2(), getW(), getH(), null);
//getImage at retrieves the frame at a "index" position from frame array.
if (getCurrentIndex() < getTotal() - 1) {
incrementIndex();//increments frame by 1 (next frame)
} else {
resetIndex();//set index to 0 (frame 0)
}
}
On the other hand, we have Display, which inheritates from JPanel and is responsible for repainting the panel (it uses I javax.swing.Timer object and repaints every 50 ms).
All the images from every Animation object have the same size 768x576 and png format with transparencies (thus I can paint many animations at a time).
The problem is that when I load an animation it occupies too much memory because it creates I don't know why either how 200 MB of "int" objects apart of the 2MB that really occupies. When I load more animations the heap's space of the JVM rockets (up to 1.7 GB... I didn't want to try anymore xD). For example, 6 animations may be 405 frames (90 in average). I've collected this data with JProfiler, but I can't post the capture so this what I get: Memory usage of my app by JProfiler:
java.awtRectangle 3351 KB
sun.java2d.SunGraphics2D 16.510 KB (I think this is the size of all the animations and sounds logical).
java.lang.String 669KB
int[] 1337 MB ...
In display, the loading images process is in this way:
add(new Animation (loadImageSet(Constants.DIR_CINTA_EJE,"all"),
Constants.A_CINTA_EJE, 75,-200,768,576));//1
Where DIR_CINTA_EJE is the directory where all the frames of that animation are and the value "all" means that I want to load all the frames.
There is a way to avoid that memory used grows linearly with the number of animations? Why those "int" values occupies so much? Are they the pixels of each image?
And yes, I have Increased my heap space up to 2GB and it's working, but at a high cost. Thank you very much for all the help you can provide. I love this forum, really.
Regards.
I've been working hard looking for a satisfactory solution and finally I've got it! That's what I have done:
Class Animation does no more inheritates from JLabel it only implements ActionListener, in which actionPerformed()
method I increment the frame to show for each one (I use Timer class). Therefore, Animation does no more override paintComponent()
method (it's work for DisplayPanel).
In DisplayPanel, I use thre global variables:
private BufferedImage _auxiliary_image;
private ImageIcon _image2display;
private ArrayList<Animation>;//I store there all the running animations there
And now, I override there the DisplayPanel paintComponent()
, thus:
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
for (int i = 0; i < _animations.size(); i++) {
if(i==0){
_auxiliary_image.createGraphics().drawImage(_animations.get(i).getActual().getImage(), 0, 0, Color.white, null);
}else{
_auxiliary_image.createGraphics().drawImage(_animations.get(i).getActual().getImage(), 0, 0, null);
}
}
_image2display.setImage(_auxiliary_image);
_image2display.paintIcon(this, g, 50, -200);
}
The reason why I difference two cases, one for i==0 and another for the rest of frames is that on painting I saw a black background and the whole positions of the animation, so is this way that I solve the issue.
Now, with 8 animations with 50 frames each one occuppies only 360 MB of memory instead 1.3 GB I get last time =) (I only paint one image, which results from merging all the frames to be printed at the same time for each animation).
Thank you and I hope this could help!!!