Спящий режим: OutOfMemoryError сохраняет большой двоичный объект при печати сообщения журнала

У меня есть Hibernate Entity:

@Entity
class Foo {
    //...
    @Lob
    public byte[] getBytes() { return bytes; }
    //....
}

Моя виртуальная машина настроена на максимальный размер кучи 512 МБ. Когда я пытаюсь сохранить объект, который имеет большой объект размером 75 МБ, я получаю ошибку OutOfMemoryError.

Названия методов в трассировке стека (StringBuilder, ByteArrayBlobType.toLoggableString, pretty.Printer.toString) предполагают, что hibernate пытается записать очень большое сообщение журнала, содержащее мой объект.

Правильно ли я понимаю, почему спящий режим использует так много памяти? Каков самый простой способ обойти эту проблему?

java.lang.OutOfMemoryError: Java heap space
at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:44)
at java.lang.StringBuilder.<init>(StringBuilder.java:81)
at org.hibernate.type.ByteArrayBlobType.toString(ByteArrayBlobType.java:117)
at org.hibernate.type.ByteArrayBlobType.toLoggableString(ByteArrayBlobType.java:127)
at org.hibernate.pretty.Printer.toString(Printer.java:53)
at org.hibernate.pretty.Printer.toString(Printer.java:90)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:97)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.jboss.seam.persistence.HibernateSessionProxy.flush(HibernateSessionProxy.java:181)

person paul    schedule 17.11.2009    source источник
comment
Вы отключили ведение журнала для гибернации?   -  person notnoop    schedule 17.11.2009


Ответы (4)


Я решил проблему. Отключение ведения журнала решило проблему, но я не понял, что при работе под сервером приложений JBoss собственный файл сервера log4j.xml переопределяет все, что я указал в пути к классам приложения.

Я открыл /jboss-4.2.3.GA/server/default/conf/log4.xml и вставил это:

<category name="org.hibernate">
    <priority value="ERROR"/>
</category>

Это устраняет проблему, которую я вижу.

person paul    schedule 17.11.2009
comment
Если вы хотите исправить это и по-прежнему получать сообщения об отладке гибернации: ‹имя категории=org.hibernate.event.def.AbstractFlushingEventListener› ‹priority value=INFO /› ‹/category› - person Anton Kuzmin; 28.06.2011

Первый тест — выяснить, действительно ли это проблема ведения журнала. Какой регистратор используете? Если это log4j, то вы можете попробовать отключить все ведение журнала из Hibernate с помощью следующей строки в вашем файле log4j.properties:

log4j.logger.org.hibernate=ВЫКЛ.

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

person delfuego    schedule 17.11.2009
comment
@delfuego: Спасибо за совет о том, как его отключить. Я создал пустой файл в корне моего пути к классам и добавил в него эту строку, и я все еще получаю много сообщений, которые приходят из спящего режима в консоли, например: 12:44:42,530 INFO [STDOUT] Hibernate: /* выберите o из разрешения o */ выберите разрешение0_.id как id21_, разрешение0_ Я поищу информацию о том, как отключить ведение журнала, так как это не работает для меня. - person paul; 17.11.2009

Красивый принтер, вероятно, преобразует байты в шестнадцатеричное представление (например, «0x55 0xF3 ...)», поэтому для каждого байта в большом двоичном объекте вы получаете 4 байта вывода, поэтому 300M вывода, это и буферизация, с другими вещами в вашей виртуальной машине вероятно ставит вас за предел.

person Justin    schedule 17.11.2009
comment
Вот о чем я думаю. Теперь мне просто нужно знать, как отключить эту функцию. :) - person paul; 17.11.2009
comment
Как насчет свойств Hibernate hibernate.show_sql=false и hibernate.format_sql=false? - person opyate; 24.09.2010

Что, если вы попробуете следующие два свойства Hibernate?

hibernate.show_sql=false
hibernate.format_sql=false
person opyate    schedule 24.09.2010