处理内存制作Swing动画

时间:2011-04-29 01:08:55

标签: java swing animation heap out-of-memory

这是我第一次在那里写作,但在阅读和搜索了很多关于我将要解释的主题后,我没有发现任何对我有用的东西(我查了一篇文章,解释了一个类似于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并且它正在工作,但成本很高。 非常感谢您提供的所有帮助。我非常喜欢这个论坛。

问候。

1 个答案:

答案 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我上次得到=)(我只绘制一个图像,这是因为合并所有要同时打印的帧每个动画)。

谢谢,我希望这可以帮助!!!