JavaRush /Java блог /Архив info.javarush /Расходование памяти в GUI приложении
Vimper
25 уровень

Расходование памяти в GUI приложении

Статья из группы Архив info.javarush
Приветствую, Джаварашовцы! Столкнулся с проблемой, нужен совет сослуживцев. Мне поступил небольшой заказ на разработку простенькой детской игры. Взялся за это дело не раздумывая, т.к. наконец-то появилась возможность сделать что-то полезное, да еще и денежку за это получить. Суть в следующем - на экране вопрос, под вопросом три варианта ответа в виде картинок. Пользователь ответил правильно - окно перерисовывается, появляется новый вопрос и новые картинки-ответы. Все это реализуется очень просто, но есть один нюанс - при смене вопроса и картинок загрузка ОЗУ неприлично возрастает, примерно на 2-3 Мб при каждом новом вопросе. При первоначальном запуске приложение занимает ~20Мб памяти, затем после >20 переключений вопросов возрастает до 60-65 Мб, что, как я понимаю, неприлично много для такого простого приложения. Анализировал эту проблему с помощью Visual VM, выяснил, что GC начинает работать только когда память кучи приближается к концу. Опытным путем выяснил, что память расходуется в этой части кода (осторожно, говнокод!): private static void drawNewImages(){ imagePanel.removeAll(); for(String fileName : DataParser.Series1Images.get(CurrentQuestion)){ ImageLabel label = new ImageLabel(fileName); imagePanel.add(label); } imagePanel.revalidate(); } Собственно здесь происходит удаление всех старых картинок-ответов и расположение новых. Картинки реализованы через JLabel. DataParser.Series1Images содержит имена файлов с картинками-ответами. Привожу код класса ImageLabel: import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.IOException; import java.io.InputStream; /** * Created by Vimper on 09.03.2015. */ public class ImageLabel extends JLabel { public static final int DEFAULT_IMAGE_WIDTH = 300; public static final int DEFAULT_IMAGE_HEIGHT = 200; private String fileName = ""; private MouseListener listener; public ImageLabel(String iconName){ super(); try (InputStream inputStream = getClass().getResourceAsStream(MusicPlayer.RESOURCES_PATH + iconName);) { Image img = ImageIO.read(inputStream); this.fileName = iconName; ImageIcon icon = new ImageIcon(img.getScaledInstance(DEFAULT_IMAGE_WIDTH_SQUARE,DEFAULT_IMAGE_HEIGHT,0)); setIcon(icon); } catch (IOException e){ e.printStackTrace(); } listener = new MouseListener() { @Override public void mouseClicked(MouseEvent e) { if(MusicPlayer.currentAudioIs(MainFrame.QUESTION_MP3)) return; if(fileName.contains(TRUE_ANSWER)){ setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.green)); endOfQuestion(); } else{ setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.red)); } } @Override public void mousePressed(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } // если курсор на картинке - меняем окантовку. @Override public void mouseEntered(MouseEvent e) { setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.gray)); } // курсор покинул картинку - возвращаем прежнюю окантовку. @Override public void mouseExited(MouseEvent e) { setBorder(BorderFactory.createEmptyBorder()); } }; addMouseListener(listener); } public void endOfQuestion(){ SwingUtilities.invokeLater(new Runnable() { public void run() { while(!MusicPlayer.musicComplete()) { try { Thread.sleep(100); } catch (InterruptedException ex) { } } MusicPlayer.setDefaultFileName(); MainFrame.NextQuestion(); }}); } } Здесь если нажата верная картинка - переходим к новому вопросу через метод endOfQuestion(), из которого впоследствии переходим к drawNewImages(): public static void NextQuestion(){ CurrentQuestion++; if(CurrentQuestion == DataParser.Questions.size()) CurrentQuestion = 0; drawNewQuestion(); drawNewImages(); } Корректно ли реализовано обновление панели с изображениями? Какие у кого есть соображения по поводу затрат ОЗУ в данном случае? Если нужно, выложу полностью исходники.
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Vimper Уровень 25
18 марта 2015
UP