Hibernate: OutOfMemoryError, сохраняющий BLOB-объект при печати сообщения журнала - PullRequest
0 голосов
/ 17 ноября 2009

У меня есть спящий объект:

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

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

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

Правильно ли я понимаю, почему 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)

Ответы [ 4 ]

3 голосов
/ 17 ноября 2009

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

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

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

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

0 голосов
/ 24 сентября 2010

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

hibernate.show_sql=false
hibernate.format_sql=false
0 голосов
/ 17 ноября 2009

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

0 голосов
/ 17 ноября 2009

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

log4j.logger.org.hibernate = OFF

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

...