Я писал маленькое 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. Я продолжу играть с ним и позволять Вам всем знать, узнаю ли я что-либо еще интересное.
Попробуйте контролировать использование кучи с помощью jconsole вместо диспетчера задач Windows:
java -Dcom.sun.management.jmxremote -jar myapp.jar
jconsole
из командной строки и подключитесь к локальному pid процесса java, который вы запустили на последнем шаге.Если вы посмотрите какое-то время, вы, вероятно, получите "пилообразный" рисунок, поскольку память со временем увеличивается, но затем имеет резкие спады. когда работает сборщик мусора. Вы можете попробовать «предложить» сборку мусора, нажав кнопку с таким названием.
Когда вы это сделаете, упадет ли использование памяти до того же минимального уровня или общий минимум увеличится в течение нескольких минут? Если минимальное использование увеличивается, значит, у вас утечка памяти. Если он всегда возвращается к одному и тому же минимальному уровню, тогда все в порядке.
Поздравляем! Вы получили первое приложение! А теперь пара вещей, о которых стоит подумать. Во-первых, диспетчер задач Windows - не лучший ресурс, чтобы понять, насколько быстро растет ваша виртуальная машина. Вместо этого вам следует отслеживать статистику сборки мусора в консоли (используйте параметр командной строки -verbose: gc
). Во-вторых, если вас беспокоят потенциальные утечки и рост виртуальной машины, существует множество отличных профилировщиков, которые просты в использовании и могут помочь вам диагностировать проблемы с памятью. ознакомьтесь с этими двумя сообщениями , чтобы узнать о некоторых вариантах профилировщика.
Поздравляем с появлением первого Java-приложения!
Java-приложения запускаются на виртуальной машине. Виртуальной машине операционная система назначила фиксированный объем памяти, обычно 512 МБ. Пока приложение использует менее 512 МБ, сборщик мусора не запускается и не начинает поиск «мертвых» блоков памяти. Предел памяти JVM можно изменить в большинстве операционных систем. Попробуйте, например, установить лимит памяти 32 МБ.
Это нормальное поведение Java?
Нет.
Я предполагаю, что мой код может вызывать утечку памяти
Это определенно причина. Пожалуйста, опубликуйте свой исходный код, иначе дальнейшая диагностика невозможна.
Я заметил, что вы используете Swing, убедитесь, что вы запускаете свой JFrame
в потоке отправки событий , используя метод invokeLater (Runnable)
.
Если вы используете какие-либо коллекции, убедитесь, что вы очистили
их после завершения.
Поскольку вы выполняете некоторый файловый ввод-вывод, убедитесь, что вы закрыли все классы, участвующие в операциях ввода-вывода, после того, как вы закончили с ними.
Если вы используете какие-либо прослушиватели событий, не забудьте явно удалить прослушиватели событий, когда они больше не нужны.
Вы можете попробовать поэкспериментировать. Возьмите свое приложение и удалите файл IO, посмотрите, что будет. Использование памяти по-прежнему поднимается? Теперь восстановите ваше приложение до нормального состояния и удалите текстовую область - память по-прежнему поднимается, как раньше? И т. Д. И т. Д. Это поможет вам определить источник, и вы сможете сосредоточить на нем свои усилия. Скорее всего, сделав это, вы откроете для себя, что вам нужно.
Другой полезный инструмент диагностики - использовать System.gc ()
в определенные моменты времени, обычно после сложных блоков кода. Это укажет JVM выполнить сборку мусора в этот момент выполнения, а не в другое время, определяемое потреблением памяти. Это поможет вам учитывать любые периодические колебания использования памяти вашим приложением.
В противном случае вы всегда можете использовать профилировщик памяти. Если вы используете IDE Netbeans, она встроена прямо в нее. Для Eclipse есть несколько плагинов, которые могут выполнять профилирование.
Это нормально. некоторые фоновые вычисления могут оставлять мертвые объекты, которые JVM не спешит очищать. в конечном итоге они будут собраны в мусор, когда будет достигнута максимальная память.
оставьте вашу программу запущенной на ночь, и ваша машина не взорвется.