Я работаю над приложением Swing, и недавно я начал видеть следующую проблему:Java GC странное поведение или утечка памяти?
Мне нужно отобразить в отдельном окне очень большой отчет о работе. Я закрываю это окно, затем снова открываю один и тот же отчет о работе, и я получаю ошибку пространства кучи OutOfMemory Java.
JVM запускается с -Xmx512m, и все объекты, созданные при открытии отчета о работе, занимают около 300 МБ в куче. Предполагая, что утечки памяти нет, я бы ожидал, что во второй раз я открою тот же отчет о работе, что JVM не будет бросать OOM. Но, глядя на журналы GC после закрытия первого окна, я не вижу никакой активности GC.
Странно то, что после того, как я закрою первое окно, если я возьму кучу кучи с jmap (без опции «live»), объекты все еще можно увидеть в дампе кучи.
Если я бегу jmap с отвала: живой вариант, в следующем режиме происходит:
- после первого дампа кучи берется, я все еще могу видеть объекты в куче.
- Когда я беру второй кучи кучи, он больше не содержит эти объекты, я могу снова открыть тот же отчет о работе, без проблем. Итак, если это была утечка памяти, тогда эти объекты не могли быть собраны, верно?
Я тестировал это на Java 6 (1.6.0_25 ad 1.6.0_45, на Windows), и он воспроизводит все время.
Запуск jmap -heap печатает:
"using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 536870912 (512.0MB)
NewSize = 1048576 (1.0MB)
MaxNewSize = 4294901760 (4095.9375MB)
OldSize = 4194304 (4.0MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 12582912 (12.0MB)
MaxPermSize = 134217728 (128.0MB)
"
JVM запускается со следующими параметрами:
" -Xms128m
-Xmx512m
-XX:MaxPermSize=128M
-verbose:gc
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-Xloggc:c:\my_gc.log
-XX:+HeapDumpOnOutOfMemoryError"
Итак, мой вопрос: почему все объекты, собранные, когда я беру дамп кучи с живым вариантом (признаком отсутствия утечки памяти), но если я этого не сделаю, я не могу повторно открыть другой (или тот же) отчет о работе, потому что получаю ошибку OOM?
Кроме того, я испытал еще один сценарий:
- открыть первое окно отчета задания, а затем закрыл его.
- создал элемент меню, который при нажатии создает бесконечный цикл Длинные экземпляры, пока JVM не выбрасывает OOM. Я проверил дамп кучи, который был сгенерирован, когда OOM был сброшен, а куча была заполнена на 99% длинными экземплярами, и ни один из объектов задания задания не был в куче.
Заранее спасибо.