问题
I have a Hibernate Entity:
@Entity
class Foo {
//...
@Lob
public byte[] getBytes() { return bytes; }
//....
}
My VM is configured with a maximum heap size of 512 MB. When I try to persist an object which has a 75 MB large object, I get an OutOfMemoryError.
The names of the methods in the stack trace (StringBuilder, ByteArrayBlobType.toLoggableString, pretty.Printer.toString) suggest that hibernate is trying to write a very large log message that contains my object.
Am I correct about why hibernate is using so much memory? What is the simplest way to work around this problem?
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)
回答1:
I solved the problem. Turning off logging did fix the problem, but I didn't understand that when running under the JBoss application server, the server's own log4j.xml file overrides whatever I put the in classpath of the application.
I opened up /jboss-4.2.3.GA/server/default/conf/log4.xml, and inserted this:
<category name="org.hibernate">
<priority value="ERROR"/>
</category>
This fixes the issue I am seeing.
回答2:
The first test is to see if it really is a logging issue. What logger are you using? If it's log4j, then you can try to turn off all logging from Hibernate with the following line in your log4j.properties file:
log4j.logger.org.hibernate=OFF
That might not be the ultimate, ideal way for your app to operate, but it might help you test whether logging is the issue.
回答3:
The pretty printer is probably converting the bytes to hex notation (e.g. '0x55 0xF3 ...)', so for each byte in the blob you get 4 bytes of output so 300M of output, that and buffering, with other stuff in your VM probably puts you over the limit.
回答4:
What if you try the following two Hibernate properties?
hibernate.show_sql=false
hibernate.format_sql=false
来源:https://stackoverflow.com/questions/1750470/hibernate-outofmemoryerror-persisting-blob-when-printing-log-message