Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Зависание GUI при быстрых методах, Как с этим бороться? 
:(
    Опции темы
Mirkes
Дата 24.10.2013, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 586
Регистрация: 18.8.2011
Где: Красноярск

Репутация: 2
Всего: 17



День добрый.
Возникла следующая проблема. К сожалению весь проект большой, выкладывать бессмысленно.
Программа реализует подбор параметров некоего регрессора путем многократных запусков с разными параметрами.
Каждый запуск производится в отдельном потоке.
Поскольку вариантов слишком много, создал специальный диалог - монитор, который дает разрешение на создание и запуск новых потоков.
Во время тестирования каждого варианта производится отображение процента выполнения на ProgressBar в том-же диалоге-мониторе. Причем для каждого потока создается свой ProgressBar (точнее TestPanel), размещаемый в диалоге. Число ProgressBar не превышает 7 для 4-ядерной машины, причем только три тестовых потока работают (специально ограничил, загрузка процессора колеблется в районе 75%).
Если тестирование одного набора параметров занимает хотя бы несколько секунд, все работает нормально.
А вот если тестирование происходит почти мгновенно, то диалог-монитор вообще не обновляется и через некоторое время выводится сообщение out of memory.
Отследил число Thread - не изменяется, то есть старые, отработавшие, освобождаются.
freeMemory конечно пляшет, но да это нормально. Если тесты работают долго, то снижения общего объема памяти не наблюдается.
А вот если тесты отрабатывают быстро, то память относительно быстро кончается (где-то после полутора тысяч тестов).

Текст монитора:
Код

package myProgress;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;


/**
 * This class serves to monitor the state of serial tests.
 * Each test is identified by thread number and has its own
 * proress bar and information label.
 * All tests can write to protocol windows
 */
public class TestProgressMonitor extends JDialog {
    @SuppressWarnings("compatibility:-1122537410441458989")
    private static final long serialVersionUID = -4159357951657064586L;

    //For singleton
    private static final TestProgressMonitor me = new TestProgressMonitor(null);

    //Protocol area
    private final JTextArea protocol = new JTextArea();

    //CloseButton
    private JButton stopB = new JButton("Close monitor");

    //To maintain threads
    private int numProc = 1;
    private int applics = 0;

    //Panel for test subpanels
    private final JPanel tests = new JPanel();
    private transient ArrayList<TestPanel> testPanels = new ArrayList<TestPanel>();

    private TestProgressMonitor(JDialog d) {
        super(d, "Tests monitor", true);
        setDefaultCloseOperation(0);
        Container cont = getContentPane();
        cont.setLayout(new BorderLayout());
        cont.add(new JScrollPane(protocol), BorderLayout.CENTER);
        tests.setLayout(new BoxLayout(tests, BoxLayout.Y_AXIS));
        cont.add(tests, BorderLayout.NORTH);
        Runtime rt = Runtime.getRuntime();
        int n = rt.availableProcessors();
        if (n > 2)
            numProc = n - 1;
        stopB.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                synchronized (stopB) {
                    stopB.notifyAll();
                }
                me.setVisible(false);
            }
        });
        cont.add(stopB, BorderLayout.SOUTH);
        setSize(500, 500);
        setLocationRelativeTo(null);
    }

    /**
     * @return the single instance of this class object
     */
    public static TestProgressMonitor getInstance() {
        return me;
    }

    /**
     * Define the possibility of start new test
     */

    public boolean mayStart(TestPanel tp) {
        return testPanels.indexOf(tp) < numProc;
    }

    /**
     * @return null if adding granted and protocol to wait otherwise
     */
    public Object mayAdd() {
        if (testPanels.size() + applics > numProc * 2)
            return protocol;
        else {
            applics++;
            System.out.println("Grant new "+applics);
            return null;
        }
    }

    /**
     * start the monitor
     */
    public synchronized void start() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                protocol.setText("");
                me.setVisible(true);
            }
        });
    }

    /**
     * Add new row to protocol
     */
    public void appendProt(final String str) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                protocol.append(str + "\n");
            }
        });
    }

    /**
     * return lock which notified only when dialog closed
     */

    public final Object getLock() {
        return stopB;
    }

    /**
     * Return exist panel for test which is asked. If there is no such panel - create it!
     */
    public synchronized TestPanel getMyPanel() {
        Thread tr = Thread.currentThread();
        for (TestPanel tp : testPanels)
            if (tr.equals(tp.thread))
                return tp;
        //There is no such thread. Create!
        final TestPanel tp = new TestPanel();
        testPanels.add(tp);
        applics--;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                stopB.setEnabled(false);
                tests.add(tp.pan);
                me.validate();
                me.repaint();
            }
        });
        
        System.out.println("Create new "+applics+"  "+testPanels.size()+"  "+Thread.activeCount()+"  "+Runtime.getRuntime().freeMemory());
        return tp;
    }

    /**
     * @param tp is the TestPanel to remove
     */
    public synchronized void stop(final TestPanel tp) {
        tp.thread = null;
        notify();
        synchronized (protocol) {
            protocol.notify();
        }
        testPanels.remove(tp);
        System.out.println("Remove "+testPanels.size());
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                if (testPanels.size() == 0)
                    stopB.setEnabled(true);
                tests.remove(tp.pan);
                me.validate();
                me.repaint();
            }
        });
    }

    /**
     * This class serves for work with one test.
     */
    public class TestPanel {
        //Panel for test data
        protected final JPanel pan = new JPanel();
        protected final JLabel lab = new JLabel("Start");
        protected final JProgressBar pb = new JProgressBar(0, 1);

        //For threade identifying
        protected Thread thread;

        public TestPanel() {
            thread = Thread.currentThread();
            pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS));
            pan.add(lab);
            pan.add(pb);
        }

        /**
         * @param text is new text for label
         * @param size is the size to add to current maximum
         */
        public void setOptions(final String text, final int size) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    pb.setMaximum(size + pb.getMaximum());
                    lab.setText(text);
                    validate();
                    repaint();
                }
            });
        }

        /**
         * @param size is the size to add to current maximum
         */
        public void setOptions(final int size) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    pb.setMaximum(size + pb.getMaximum());
                    repaint();
                }
            });
        }

        /**
         * Add 1 to current value
         */
        public void addStep() {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    pb.setValue(pb.getValue() + 1);
                }
            });
        }

        /**
         * Stop work of this test
         */
        public void stop() {
            me.stop(this);
        }
    }
}


У меня сложилось впечатление, что поскольку отрисовка не происходит, то в EDT происходит накопление запросов, каждый из которых ссылается на свой TestPanel. Как следствие TestPanel относящиеся к уже отработавшим тестам не освобождаются.

Вопрос, как принудить EDT работать?
Если заменить все invokeLater на invokeAndWait - начнут тормозить тесты, не хотелось бы.
Что посоветуете?


--------------------
Mirkes
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0797 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.