这是我第一次在那里写作,但在阅读和搜索了很多关于我将要解释的主题后,我没有发现任何对我有用的东西(我查了一篇文章,解释了一个类似于iPhone应用程序,但没有最终的解决方案)。抱歉我的英语我会尽力做到最好呵呵:)。
好的,我正在开始:我有一个java应用程序,它在JPanel上同时显示一组动画。这些动画是来自动画(继承自JLabel)的java对象,这是我自己的类,它存储了一个ImageIcon (表示动画帧)和一个整数指针的数组,显示要绘制的实际帧(索引)。 该类以这种方式覆盖了方法setPaint():
@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)
}
}
另一方面,我们有显示,它继承自JPanel并负责重新绘制面板(它使用I javax.swing.Timer对象,每50毫秒重绘一次)。
每个动画对象的所有图像都具有相同的大小768x576和png格式的透明度(因此我可以一次绘制多个动画)。
问题在于,当我加载一个动画时,它会占用太多内存,因为它创建了我不知道为什么200 MB的“int”对象除了真正占用的2MB之外。当我加载更多动画时,JVM火箭的堆空间(高达 1.7 GB ......我不想再尝试xD了)。例如, 6个动画可能是405帧(平均90帧)。 我已经用JProfiler收集了这些数据,但是我不能发布捕获所以我得到的结果: JProfiler对我的应用程序的内存使用情况:
java.awtRectangle 3351 KB
sun.java2d.SunGraphics2D 16.510 KB(我认为这是所有动画和声音的大小合乎逻辑)。
java.lang.String 669KB
int [] 1337 MB ...
在显示中,加载图像处理是这样的:
add(new Animation (loadImageSet(Constants.DIR_CINTA_EJE,"all"),
Constants.A_CINTA_EJE, 75,-200,768,576));//1
其中DIR_CINTA_EJE是该动画的所有帧的目录,值“all”表示我想加载所有帧。
有一种方法可以避免使用的内存与动画的数量呈线性增长吗?为什么那些“int”值占据如此之多?它们是每个图像的像素吗?
是的,我已经将堆空间增加到2GB并且它正在工作,但成本很高。 非常感谢您提供的所有帮助。我非常喜欢这个论坛。
问候。
答案 0 :(得分:1)
我一直在努力寻找一个满意的解决方案,最后我得到了它! 这就是我所做的:
类动画不再继承JLabel它只实现了ActionListener,其中actionPerformed()
方法我递增每个帧显示的帧(我使用Timer类)。因此,Animation不再覆盖paintComponent()
方法(它适用于DisplayPanel)。
在DisplayPanel中,我使用了thre全局变量:
private BufferedImage _auxiliary_image;
private ImageIcon _image2display;
private ArrayList<Animation>;//I store there all the running animations there
现在,我在那里覆盖DisplayPanel paintComponent()
,因此:
@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);
}
我区分两种情况的原因,一种是i == 0,另一种是其余的框架,是因为在绘画上我看到了黑色背景和动画的整个位置,所以这就是我解决问题的方法
现在,有8个动画,每个50帧,一个只占用360 MB内存而不是1.3 GB我上次得到=)(我只绘制一个图像,这是因为合并所有要同时打印的帧每个动画)。
谢谢,我希望这可以帮助!!!