Использование памяти JAVA-приложения

Я писал маленькое JAVA-приложение (мое первое!), который делает только несколько вещей в данный момент. В настоящее время это выполняет Основной класс, который запускает gui класс (класс, я записал, что это расширяет JFrame, который только содержит JTextArea), класс, который загружает локальный файл через BufferedInputStream, который составляет приблизительно 40 КБ, и класс, который загружает запись из файла свойств Java.

Все работает замечательно, однако, я наблюдал диспетчер задач Windows, и я заметил что-то, что показалось мне нечетный. Когда я запускаю приложение, переходы Использования оперативной памяти приблизительно к 40 МБ, в то время как оно загружает локальный файл и вытягивает несколько значений от него для отображения в JTextArea, который кажется нормальным мне из-за JVM, базовых классов Java, и т.д. На данном этапе однако, когда приложение закончило загружать файл, itmerely простаивает, поскольку у меня в настоящее время нет его делающий ничто больше. В то время как это простаивает, пока окно активно, использование памяти приложения начинает подниматься 10-20kb каждую секунду. Это кажется мне нечетный. Если я нажимаю на другую программу для создания этого неактивным окном, память все еще повышается, но на намного более медленном уровне (приблизительно 10 КБ каждые 3-5 секунд).

Я не протестировал, чтобы видеть, как далеко это повысилось бы, но это кажется мне очень нечетным поведением. Это нормальное поведение Java? Я предполагаю, что возможно, что мой код мог пропускать память, но я не уверен как. Я действительно удостоверялся, что закрыл BufferedInputStream, который я использую, и я не вижу то, что еще вызвало бы это.

Я сожалею, если бы мое объяснение не имеет смысла, но я ценил бы любое понимание и/или указатели, которые любой может иметь.

ОБНОВЛЕНИЕ:

На предложение я в основном разделил свое приложение вниз к Основному классу, который просто называет gui класс. gui класс только расширяет JFrame и устанавливает размер окна, операцию закрытия и свойства видимости. С этими изменениями память все еще растет на 10-20kb, но на более медленном уровне. Это, в conjuction с другим советом, который я получил, приводит меня полагать, что это - просто Java. Я продолжу играть с ним и позволять Вам всем знать, узнаю ли я что-либо еще интересное.

7
задан Jason Watkins 30 June 2010 в 02:53
поделиться

5 ответов

Попробуйте контролировать использование кучи с помощью jconsole вместо диспетчера задач Windows:

  • Запустите приложение с параметром -Dcom.sun.management.jmxremote, например

java -Dcom.sun.management.jmxremote -jar myapp.jar

  • Запустите jconsole из командной строки и подключитесь к локальному pid процесса java, который вы запустили на последнем шаге.
  • Щелкните по памяти и просмотрите память кучи (отображение по умолчанию)

Если вы посмотрите какое-то время, вы, вероятно, получите "пилообразный" рисунок, поскольку память со временем увеличивается, но затем имеет резкие спады. когда работает сборщик мусора. Вы можете попробовать «предложить» сборку мусора, нажав кнопку с таким названием.

Когда вы это сделаете, упадет ли использование памяти до того же минимального уровня или общий минимум увеличится в течение нескольких минут? Если минимальное использование увеличивается, значит, у вас утечка памяти. Если он всегда возвращается к одному и тому же минимальному уровню, тогда все в порядке.

9
ответ дан 6 December 2019 в 14:00
поделиться

Поздравляем! Вы получили первое приложение! А теперь пара вещей, о которых стоит подумать. Во-первых, диспетчер задач Windows - не лучший ресурс, чтобы понять, насколько быстро растет ваша виртуальная машина. Вместо этого вам следует отслеживать статистику сборки мусора в консоли (используйте параметр командной строки -verbose: gc ). Во-вторых, если вас беспокоят потенциальные утечки и рост виртуальной машины, существует множество отличных профилировщиков, которые просты в использовании и могут помочь вам диагностировать проблемы с памятью. ознакомьтесь с этими двумя сообщениями , чтобы узнать о некоторых вариантах профилировщика.

2
ответ дан 6 December 2019 в 14:00
поделиться

Поздравляем с появлением первого Java-приложения!

Java-приложения запускаются на виртуальной машине. Виртуальной машине операционная система назначила фиксированный объем памяти, обычно 512 МБ. Пока приложение использует менее 512 МБ, сборщик мусора не запускается и не начинает поиск «мертвых» блоков памяти. Предел памяти JVM можно изменить в большинстве операционных систем. Попробуйте, например, установить лимит памяти 32 МБ.

2
ответ дан 6 December 2019 в 14:00
поделиться

Это нормальное поведение Java?

Нет.

Я предполагаю, что мой код может вызывать утечку памяти

Это определенно причина. Пожалуйста, опубликуйте свой исходный код, иначе дальнейшая диагностика невозможна.

Я заметил, что вы используете Swing, убедитесь, что вы запускаете свой JFrame в потоке отправки событий , используя метод invokeLater (Runnable) .

Если вы используете какие-либо коллекции, убедитесь, что вы очистили их после завершения.

Поскольку вы выполняете некоторый файловый ввод-вывод, убедитесь, что вы закрыли все классы, участвующие в операциях ввода-вывода, после того, как вы закончили с ними.

Если вы используете какие-либо прослушиватели событий, не забудьте явно удалить прослушиватели событий, когда они больше не нужны.


Вы можете попробовать поэкспериментировать. Возьмите свое приложение и удалите файл IO, посмотрите, что будет. Использование памяти по-прежнему поднимается? Теперь восстановите ваше приложение до нормального состояния и удалите текстовую область - память по-прежнему поднимается, как раньше? И т. Д. И т. Д. Это поможет вам определить источник, и вы сможете сосредоточить на нем свои усилия. Скорее всего, сделав это, вы откроете для себя, что вам нужно.

Другой полезный инструмент диагностики - использовать System.gc () в определенные моменты времени, обычно после сложных блоков кода. Это укажет JVM выполнить сборку мусора в этот момент выполнения, а не в другое время, определяемое потреблением памяти. Это поможет вам учитывать любые периодические колебания использования памяти вашим приложением.

В противном случае вы всегда можете использовать профилировщик памяти. Если вы используете IDE Netbeans, она встроена прямо в нее. Для Eclipse есть несколько плагинов, которые могут выполнять профилирование.

1
ответ дан 6 December 2019 в 14:00
поделиться

Это нормально. некоторые фоновые вычисления могут оставлять мертвые объекты, которые JVM не спешит очищать. в конечном итоге они будут собраны в мусор, когда будет достигнута максимальная память.

оставьте вашу программу запущенной на ночь, и ваша машина не взорвется.

1
ответ дан 6 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: