#java #junit #jvm #сборщик_мусора
jUnit тесты работают с большими объемами данных, в частности, данная ошибка возникает, когда считываем данные из базы в объект. ОЗУ - 16 Гб, 4 виртуальных процессора когда возникла ошибка java.lang.OutOfMemoryError: GC overhead limit exceeded at sun.reflect.GeneratedConstructorAccessor47.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:422) at java.lang.Class.newInstance(Class.java:442) то я добавил параметр -XX:-UseGCOverheadLimit но получил следующую ошибку: java.lang.OutOfMemoryError: GC overhead limit exceeded at java.lang.reflect.Field.copy(Field.java:150) at java.lang.reflect.ReflectAccess.copyField(ReflectAccess.java:144) at sun.reflect.ReflectionFactory.copyField(ReflectionFactory.java:309) at java.lang.Class.copyFields(Class.java:3115) at java.lang.Class.getFields(Class.java:1557) at main.java.DataFormat.DbTable.loadObjectFromResultSet(DbTable.java:101) at main.java.DataFormat.DbTable.getEntities(DbTable.java:57) все параметры JVM -Xmx8192M -XX:-UseGCOverheadLimit в момент появления ошибки были следующие параметры системы: ОЗУ стабильно на 46% (7400Мб), ЦПУ 77%-82% (82% в момент появления ошибки) подскажите, как исправить данную проблему? Спарвка java.lang.OutOfMemoryError: GC overhead limit exceeded Данная ошибка может возникнуть как при переполнении первой, так и второй областей. Связана она с тем, что памяти осталось мало и GC постоянно работает, пытаясь высвободить немного места. Данную ошибку можно отключить с помощью параметра -XX:-UseGCOverheadLimit, но, конечно же, её надо не отключать, а либо решать проблему утечки памяти, либо выделять больше объема, либо менять настройки GC. Ответ String объект слишком много весит. а у меня там очень много стрингов. Для примера, посчитали файл, который весит 250 МБ, имеет 1600 символов в строке и 220 000 строк. Заполняю в ArrayListlines, где каждая строка записана как объект из 250 полей, которые принимают значение из 1600 символов. Такой объект весил чуть больше 6Гб. Решение: увеличил память до 14Гб. теперь проблема в том, что 6Гбайтный объект не помещается в куче, надо думать что-то другое и пожертвовать временем выполнения теста.
Ответы
Ответ 1
В данном случае ошибка java.lang.OutOfMemoryError: GC overhead limit exceeded говорит о том, что Вы пытаетесь обработать такой объем данных который не помещается в память. В приведенной Вами справке упомянуто, что ошибка выбрасывается, когда область памяти, занимаемая только, что созданными объектами переполняется. Плюс к этому в трассировке стека видно, что ваши классы ( at main.java.DataFormat.DbTable.loadObjectFromResultSet(DbTable.java:101) at main.java.DataFormat.DbTable.getEntities(DbTable.java:57) ) в момент получения ошибки как раз пытаются выгрузить данные из базы. Поэтому простой и неутешительный вывод из вышесказанного тестируйте на меньшем объеме данных или выделяйте больший объем под выгружаем данные(-Xmx12000M) если они туда поместятся, то ошибка исчезнет. Настраивать сборку мусора в данном случае бесполезно т.к. GC не сможет удалить загружаемые объекты потому как они еще используются.Ответ 2
Начту с основ для лучшего понимания ошибки. JVM имеет две области памяти: Heap Memory и Non-Heap Memory. Heap Memory - хранит объекты; Non-Heap Memory - хранит параметры методов, примитивные типы и т.д. В Вашем случае происходит переполнение Heap Memory, т.к. очень много создается объектов, которые не вмещаются в Heap Memory. Решить проблему можно увеличив Heap Memory (ключ -Xmx), что не всегда помогает, т.к. объем данных может быть больше чем доступно ОЗУ, поэтому лучше реализовать обработку данных из БД порционно, т.е. выгружать часть данных, чтобы объекты поместились в памяти, затем убивать их (присваивать null, чтобы GC разгрузить), замет следующею часть и т.д. P.S. Стоит понимать, что Heap не равно ОЗУ. Heap - это только зарезервированная память для JVM, больше данного резерва JVM использовать не может даже, если ОЗУ в избытке.
Комментариев нет:
Отправить комментарий