我有一个Hibernate实体:
@Entity
class Foo {
//...
@Lob
public byte[] getBytes() { return bytes; }
//....
}
我的VM配置的最大堆大小为512 MB。当我尝试持久化具有75 MB大对象的对象时,我得到一个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)
答案 0 :(得分:3)
我解决了这个问题。关闭日志记录确实解决了问题,但我不明白在JBoss应用程序服务器下运行时,服务器自己的log4j.xml文件会覆盖我在应用程序的类路径中放置的任何内容。
我打开了/jboss-4.2.3.GA/server/default/conf/log4.xml,插入了这个:
<category name="org.hibernate">
<priority value="ERROR"/>
</category>
这解决了我所看到的问题。
答案 1 :(得分:0)
第一个测试是看它是否真的是一个日志记录问题。你用什么记录器?如果它是log4j,那么您可以尝试使用log4j.properties文件中的以下行关闭来自Hibernate的所有日志记录:
log4j.logger.org.hibernate = OFF
这可能不是您的应用运行的最佳,理想的方式,但它可能会帮助您测试日志记录是否是问题。
答案 2 :(得分:0)
漂亮的打印机可能会将字节转换为十六进制表示法(例如'0x55 0xF3 ...)',因此对于blob中的每个字节,您将获得4个字节的输出,因此300M的输出,即缓冲和其他内容在您的虚拟机中可能会超出限制。
答案 3 :(得分:0)
如果您尝试以下两个Hibernate属性怎么办?
hibernate.show_sql=false
hibernate.format_sql=false