Работа с памятью, создающая анимацию Swing - PullRequest
2 голосов
/ 29 апреля 2011

Я впервые пишу там, но после прочтения и поисков предмета, который я собираюсь объяснить, я не нашел ничего полезного для себя (я проверил сообщение парня, объясняющего что-то похожее приложение для iphone, но без окончательного решения). Извините за мой английский, я постараюсь сделать все возможное, хе-хе:).

Хорошо, я начинаю: у меня есть java-приложение, которое одновременно показывает набор анимаций на JPanel. Эти анимации представляют собой Java-объекты из Animation (наследует от JLabel), мой собственный класс , который хранит массив 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)
        }
}

С другой стороны, у нас есть Display , который наследуется от JPanel и отвечает за перерисовку панели (он использует I javax.swing.Timer объект и перерисовывается каждые 50 мс ).

Все изображения из каждого объекта Анимация имеют одинаковый размер 768x576 и формат png с прозрачностью (таким образом, я могу рисовать много анимаций одновременно).

Проблема в том, что когда я загружаю анимацию, она занимает слишком много памяти, потому что она создает, и я не знаю, почему 200 МБ объектов типа int помимо 2 МБ, которые действительно занимают. Когда я загружаю больше анимаций, пространство кучи ракет JVM (до 1,7 ГБ ... я не хотел больше пробовать xD). Например, 6 анимаций могут составлять 405 кадров (в среднем 90). Я собрал эти данные с помощью JProfiler, но я не могу опубликовать запись, так что я получаю: Использование памяти моего приложения JProfiler:

  • java.awtRectangle 3351 KB

  • sun.java2d.SunGraphics2D 16,510 КБ (я думаю, что это размер всех анимаций и логических звуков).

  • java.lang.String 669KB

  • int [] 1337 МБ ...


На дисплее процесс загрузки изображений происходит следующим образом:

add(new Animation (loadImageSet(Constants.DIR_CINTA_EJE,"all"),
            Constants.A_CINTA_EJE, 75,-200,768,576));//1

Где DIR_CINTA_EJE - каталог, в котором находятся все кадры этой анимации, а значение "all" означает, что я хочу загрузить все кадры.

Есть способ избежать линейного увеличения используемой памяти с количеством анимаций? Почему эти "int" значения занимают так много? Являются ли они пикселями каждого изображения?

И да, я увеличил пространство кучи до 2 ГБ, и это работает, но за высокую цену. Большое спасибо за всю помощь, которую вы можете оказать. Мне очень нравится этот форум.

Привет.

1 Ответ

1 голос
/ 03 мая 2011

Я усердно искал удовлетворительное решение, и, наконец, оно у меня есть!Вот что я сделал:

Class Animation больше не наследует от JLabel, он реализует только ActionListener, в котором actionPerformed() метод я увеличиваю кадр, чтобы показать для каждого (я использую класс Timer).Поэтому анимация больше не переопределяет метод paintComponent() (он работает для DisplayPanel).

В DisplayPanel я использую глобальные переменные:

private BufferedImage _auxiliary_image;
private ImageIcon _image2display;
private ArrayList<Animation>;//I store there all the running animations there

И теперь я переопределяю там DisplayPanelpaintComponent(), таким образом:

 @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 МБ памяти вместо 1,3 ГБ, я получаю в последний раз =) (Я рисую только одно изображение, что является результатом объединения всех кадров, которые должны быть напечатаны одновременно для каждой анимации).

Спасибо, и я надеюсь, что это может помочь !!!

...