Почему прокрутка JTable занимает так много памяти? - PullRequest
1 голос
/ 02 января 2012

Здравствуйте, я программирую двухпанельный файловый менеджер на Java, и я сталкиваюсь с проблемой.

Всякий раз, когда я прокручиваю JTable, это занимает примерно 8 МБ памяти ... Есть ли способ, как это исправить?Он останавливается каждый раз после использования 40 - 60M памяти.Это проблема Swing компонента?

Спасибо за ваши ответы.

Редактировать

Я пытался понять, почему это занимает столько памяти,Теперь я знаю источник проблемы.Я сделал маленькую кнопку с этим действием Выполнено: jScrollPane1.repaint();.

Когда я нажал 10 раз, у меня было большое потребление памяти в диспетчере задач, а также в VisualVM.Но в VisualVM GC начинает собирать по 50 МБ и понижает его до 8 МБ.Но Windows TaskManager все еще увеличивает свою ценность.

Метод перекраски вызывает большие утечки памяти в Windows.Есть ли какое-нибудь исправление?

Edit2

Дальнейшее исследование этой проблемы дало мне это.Я попытался запустить эту программу на платформе Linux без утечки.В программе было использовано около 20 М памяти.Итак, я запрограммировал небольшой поток, который вызывал перерисовку метода на обоих JScrollPanes.И, к моему удивлению, на Windows машинная память росла до 110 Мб, но затем ОС стала сильнее давить на память.

Поток:

@Override
public void run() {
        while (true) {
            jScrollPane1.repaint();
            jScrollPane2.repaint();
            try {
                this.sleep(10);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

Я делал обычные операции копирования / переименования / удаления, также просматривал каталоги без увеличения памяти.Я заметил, что память также уменьшается до 99M.

В потоке мониторинга:

@Override
public void run() {
    while (true) {
        aLabel.setText("Memory consumption: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
        try {
            this.sleep(200);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}

числа были от 8M до 50M, а затем снова 8M.Так что сборка мусора прошла успешно.Таким образом, реальная проблема - платформа Windows или совместимость JVM?Как предположил trashgod, диспетчер задач не является точным в определении потребления памяти, но память действительно используется процессом Java.

Ответы [ 2 ]

1 голос
/ 02 января 2012

Вызов FileSystemView.getFileSystemView() может быть проблемой, как предложено здесь и профилировано здесь .Это может помочь отредактировать ваш вопрос, добавив sscce , который демонстрирует проблему.Использование профилировщика может указывать на масштаб и серьезность проблемы; Java VisualVM может быть уже установлен.

Диспетчер задач Windows все еще увеличивает свое значение.

Диспетчер задач Windows может быть не полностью диспозитивнымкак предложено здесь .В этом контексте результат jvisualvm может быть более надежным.

0 голосов
/ 03 января 2012

никогда не используйте Thread#sleep во время EDT, по этой причине вы получаете un_expecting UsedMemory,

1) Swing GUI является однопоточным

2) Swing GUI ожидает всех выполненных событий,все изменения выполняются на экране в одно мгновение, включая использование Thread#sleep,

3) с помощью Thread#sleep вы можете смоделировать и увидеть на экране не ожидаемую перерисовку графического интерфейса, или значение не обновляется илиперекрасил

4) у вас проблемы с Concurency в Swing

5) Я не вижу причин для использования repaint(), обратите внимание, что очень сложный метод дляместная среда

6) использовать и переносить код в

7), так как у меня есть несколько методовкогда требуется (преднамеренное) использование Thread#sleep, непростая работа без охвата Controler всей EDT

...