У меня приложение, которое использует довольно много актеров : 25 000, если быть точным. Он использует Scala 2.7.7 и работает на jdk6_u18 . Он в основном слушает и обрабатывает рыночные данные и имеет очень небольшое состояние.
Он начинается в 8.02 утра каждый день, и в течение часа он падает с OutOfMemoryError
. «Ага, - говорите вы, - у вас утечка памяти!» За исключением того, что, когда я перезапускаю его, он никогда , когда-либо снова падает на весь оставшийся день! И это несмотря на увеличение нагрузки на ГХ и ЦП, когда рынки США открываются в 14:30.
Несколько анекдотических выводов:
- он работает на Solaris. Когда я запускал его в Linux, он никогда не падал вообще .
- Я пробовал возиться с определением размера кучи для генерации, выделять больше памяти и т.д.
- Поведение коллектора, кажется, отличается, когда у меня
verbose:gc
включен
Возникают несколько вопросов:
- Почему поведение этой программы может отличаться в Linux и Solaris?
- Почему было бы иначе поведение, начиная с 8.02 и начиная с 8.42?
- Я слышал, что в библиотеке актеров были проблемы с утечкой памяти. Кем они были, когда их исправили и как я узнал, что здесь может происходить что-то «похожее»? (Что нужно искать в jhat и т. Д.)
- Кто-нибудь имеет представление о том, что может происходить?
Я сейчас пытаюсь G1
узнать, имеет ли это какое-то значение. Я обновлю этот вопрос завтра!
Некоторый вывод из G1 с многословным: gc on
Кажется, я только что понял это:
600,290: [Полная GC 255M-> 144M (256M), 1,5772616 секунд]
602,084: [GC пауза (молодые) 227M-> 145M (256M), 0,0556769 с]
602,418: [Полный GC 254M-> 144M (256M), 1,6415216 с]
604,279: [пауза GC (молодые) 227M-> 145M (256M), 0,0415157 с]
604.602: [Полная ГХ 255М-> 145М (256М), 1,6041762 с]
606,422: [GC пауза (молодые) 227M-> 145M (256M), 0,0237441 с]
606,710: [Полный GC 254M-> 145M (256M), 1,6022185 с]
А потом немного позже (вы можете видеть, что полный сборщик мусора занял больше времени и требует меньше)
849,084: [Полный GC 254M-> 176M (256M), 1,9658754 с]
851,191: [GC пауза (молодые) 228M-> 176M (256M), 0,0218611 с]
851,414: [Полный GC 254M-> 176M (256M), 1,9352357 с]
853,492: [GC пауза (молодые) 228M-> 176M (256M), 0,0224688 с]
853,716: [Полный GC 254M-> 176M (256M), 1,9339705 секунд]
855,793: [GC пауза (молодые) 228M-> 176M (256M), 0,0215707 с]
856,009: [Полная GC 254M-> 176M (256M), 1,9805797 с]
858,137: [GC пауза (молодые) 228M-> 176M (256M), 0,0223224 секунды]
Некоторый вывод из G1 с подробным текстом: gc off
Это снова хорошо! * Вздох *
303,656: [пауза GC (молодые) 225M-> 93M (256M), 0,1680767 с]
308,060: [GC пауза (молодые) 226M-> 94M (256M), 0,1793724 с]
312,746: [GC пауза (молодые) 227M-> 93M (256M), 0,1674851 с]
316.162: [пауза GC (молодой) 227M-> 95M (256M), 0,1826145 с]
320,147: [GC пауза (молодые) 226M-> 94M (256M), 0,1656664 секунды]
325,978: [GC пауза (молодые) 226M-> 93M (256M), 0,1475760 с]
330,176: [GC пауза (молодые) 226M-> 94M (256M), 0,1727795 с]
и много, много позже все еще в порядке!
25882,894: [пауза GC (молодые) 224M-> 125M (256M), 0,2126515 с]
25884,880: [GC пауза (молодые) 224M-> 126M (256M), 0,2059802 с]
25887,027: [GC пауза (молодые) 224M-> 125M (256M), 0,1851359 с]
25889,940: [GC пауза (молодые) 223M-> 126M (256M), 0,2046496 с]
25891,567: [GC пауза (молодые) 224M-> 126M (256M), 0,1600574 с]
и позже, полный GC
37180.191: [пауза GC (младшая) 225M-> 154M (256M), 0,1716404 с]
37182.163: [пауза GC (молодая) (начальная отметка) 225M-> 153M (256M) 37182,326: [одновременная GC-mark-start], 0,1622246 с]
37183,089: [Конец одновременной отметки GC, 0,7635219 с]
37183,090: [Замечание GC, 0,0032547 с]
37183,093: [запуск одновременного подсчета GC]
37183.297: [Конец одновременного подсчета ГХ, 0,2043307]
37183,393: [Очистка ГХ 198M-> 198М (256М), 0,0068127 с]
37183.400: [Запуск одновременной очистки ГХ]
37183,400: [Конец одновременной очистки GC, 0,0000393]
37183,648: [Пауза GC (молодая) 222M-> 153M (256M), 0,1483041 с]
37184.235: [Пауза GC (частичная) 171M-> 91M (256M), 0,2520714 секунд]
37187,223: [GC пауза (молодые) 221M-> 92M (256M), 0,1721220 секунд]
ОБНОВЛЕНИЕ
Хорошо, так как переключение наG1 сборщик мусора на jdk1.6.0_18 приложение вело себя три дня подряд.Я подозреваю, что Эрик прав в своем анализе ситуации о том, что ВМ попадает в спираль смерти в случаях с высокой пропускной способностью, когда она продвигает объекты в штатное поколение.