У меня есть Java-программа, которая работает на моем компьютере Ubuntu 10.04 и без какого-либо взаимодействия с пользователем неоднократно запрашивает базу данных MySQL, а затем создает img- и txt файлы в соответствии с данными, считываемыми из БД. Он обрабатывает десятки тысяч запросов и создает десятки тысяч файлов.
После нескольких часов работы доступная память на моей машине, включая пространство подкачки, полностью израсходована. Я не запускал другие программы, и процессы, выполняющиеся в фоновом режиме, не потребляют много памяти и не растут в потреблении.
Чтобы узнать, что выделяет столько памяти, я хотел проанализировать кучу кучи, поэтому я начал процесс с -Xms64m -Xmx128m -XX: + HeapDumpOnOutOfMemoryError.
К моему удивлению, ситуация была такой же, как и раньше, через несколько часов программа выделяла весь своп, который выходит за пределы заданного максимума 128 м.
Другой запуск, отлаженный с помощью VisualVM, показал, что распределение кучи никогда не превышает максимальный 128 м - когда выделенная память приближается к максимальному, большая часть его снова освобождается (я предполагаю сборщик мусора).
Таким образом, это не может быть проблемой неуклонно растущей кучи.
Когда вся память испорчена:
бесплатно показывает следующее:
total used free shared buffers cached
Mem: 2060180 2004860 55320 0 848 1042908
-/+ buffers/cache: 961104 1099076
Swap: 3227640 3227640 0
top показывает следующее:
USER VIRT RES SHR COMMAND
[my_id] 504m 171m 4520 java
[my_id] 371m 162m 4368 java
(безусловно, два "самых больших" процесса и только запущенные java-процессы)
Мой первый вопрос:
- Как я могу узнать на уровне ОС (например, с помощью средств командной строки), что выделяет столько памяти? top/htop мне не помог. В случае многих, многие крошечные процессы того же типа едят память: есть ли способ разумно суммировать подобные процессы? (Я знаю, что это, вероятно, вне темы, поскольку это вопрос Linux/Ubuntu, но моя основная проблема все еще может быть связана с Java)
Мои старые вопросы:
- Почему не используется память моей программы в верхнем выпуске?
- Как узнать, что выделяет столько памяти?
- Если куча не является проблемой, является единственным "распределяющим фактором" стека? ( стек не должен быть проблемой, так как нет глубокой "глубины вызова метода" )
- Как насчет внешних ресурсов как соединений DB?