Hibernate:打印日志消息时出现 OutOfMemoryError 持久化 Blob
我有一个 Hibernate 实体:
@Entity
class Foo {
//...
@Lob
public byte[] getBytes() { return bytes; }
//....
}
我的 VM 配置的最大堆大小为 512 MB。当我尝试保留一个具有 75 MB 大对象的对象时,我收到 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)
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我解决了这个问题。关闭日志记录确实解决了问题,但我不明白,当在 JBoss 应用程序服务器下运行时,服务器自己的 log4j.xml 文件会覆盖我在应用程序的类路径中放置的任何内容。
我打开 /jboss-4.2.3.GA/server/default/conf/log4.xml,并插入以下内容:
这解决了我所看到的问题。
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:
This fixes the issue I am seeing.
第一个测试是看看这是否确实是日志记录问题。您使用什么记录器?如果是 log4j,那么您可以尝试在 log4j.properties 文件中使用以下行来关闭 Hibernate 的所有日志记录:
这可能不是您的应用程序运行的最终、理想的方式,但它可能会帮助您测试日志记录是否是问题所在。
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:
That might not be the ultimate, ideal way for your app to operate, but it might help you test whether logging is the issue.
漂亮的打印机可能会将字节转换为十六进制表示法(例如“0x55 0xF3 ...)”,因此对于 blob 中的每个字节,您将获得 4 个字节的输出,因此 300M 的输出,以及缓冲,以及 VM 中的其他内容可能会让你超出极限。
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.
如果您尝试以下两个 Hibernate 属性会怎样?
What if you try the following two Hibernate properties?