微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Hibernate 延迟加载 LOB如何卸载已处理的对象以停止消耗内存?

如何解决Hibernate 延迟加载 LOB如何卸载已处理的对象以停止消耗内存?

在处理带有 LOB 的记录时,请有人帮助我解决内存问题! 所以我有以下情况:我有两个表,其中一个是包含一些数据的表。该表的一列具有到第二个表的“一对多”映射。 第二个表保存了存储在 LOB 中的数百万张照片图像。 我使用“延迟加载”方法来访问图像。我需要迭代第一个表的记录以获取照片和其他信息并将它们发送到某个 SOAP 门。 每次新数据落入表中时,我都需要定期重新启动该过程。 所以我做了,它在一段时间内运行良好,但突然停止,出现如下异常:

июн 08,2021 3:23:44 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PoolState stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:postgresql://x.x.x.x:yyyy/SomeDbInstance]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:92)

那是我的应用程序耗尽了所有内存并因此错误而停止执行。

所以我的问题是:是否可以清理已处理的条目以释放它们在加载后开始消耗的内存?

解决方法

谢谢凯文的建议!我启动了 Java Visual VM,使用分析器、堆转储和监视器来分析我的服务的执行过程。所以,我发现堆中挂着许多重的 LOB 实例。而且,是的,我必须发明方法来清除它们。我似乎明白了!

for (PhotoContext pc:tr.getPhotoContext()) {

    . . .

    photo.setPhotoType(photoTypeMapping(pc.getInd()));
    GregorianCalendar gk = new GregorianCalendar();
    gk.setTime(pc.getDatetime());
    photo.setDatetime(DatatypeFactory.newInstance().newXMLGregorianCalendar(gk));
    photo.setPhoto(Arrays.copyOf(pc.getPhoto(),pc.getPhoto().length));
    photos.add(photo);

    sourceDao.getSession().evict(pc);
    pc.setPhoto(null);
}

我不得不分离照片条目,然后将其照片字段(字节[])设置为空。也许这不是特别优雅,但确实有效。

,

延迟加载允许您推迟将某些内容加载到内存中,直到您需要它为止。它不会阻止您将太多内容加载到内存中并用完堆。您需要考虑如何根据需要加载对象,处理它们,然后释放引用,以便 GC 可以释放堆中的空间。

其他需要考虑的事项:

  • 使用分析器,以便了解您的应用在运行时如何使用和消耗堆
  • 使用 JVM gc 标志在运行时观察 gc 性能 - 您是否正在释放引用以便 GC 可以执行收集?收集需要多长时间?您创建新实例的速度是否比 GC 释放堆空间的速度快?
  • 您的堆大小是否适合您尝试处理的数据大小?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。