2013-04-28 2 views
1

Я работаю над приложением 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% длинными экземплярами, и ни один из объектов задания задания не был в куче.

Заранее спасибо.

ответ

1

Итак, мой вопрос: почему все объекты, собранные, когда я беру дамп кучи с живым вариантом

jmap живого вариант заставляет коллекцию. Обсуждалось here.

Ваши наблюдения подтверждают это.

Что может быть сделано в качестве упражнения, это повторное открытие окна после некоторого действия GC, чтобы увидеть, была ли память восстановлена.

Смежные вопросы