【发布时间】:2014-02-04 10:58:53
【问题描述】:
我正在分析我的 web 应用程序(使用 Spring + Hibernate),并发现在必须将服务方法解析为事务性时,我会使用大量内存。
这是从控制器调用服务方法:
User e = userService.getUser();
这是服务中的上述方法:
@Transactional(readOnly = true)
public User getUser(Long id) throws GenericDataBaseException, InstanceNotFoundException {
User e = userDao.findById(id);
return e;
}
通过调试我的应用程序,我在方法调用(第一个代码 sn-p)中放置了一个断点,并在 getUser() 的第一行放置了另一个断点。现在只有 @Transactional 注释的注入和方面解析会触发 30 mb 的内存使用。这是 VisualVM 的屏幕截图:
你看到的颠簸是由这个电话引起的。现在,如果单个控制器方法多次调用事务服务方法,这会累积到大约 100MB 的内存使用量。这可能是垃圾收集,所以它不是内存泄漏,但我很好奇可能导致这个问题的原因,以及它是否是正常行为。这仅在第一次调用事务方法时发生。连续调用几乎不占用内存。
编辑:这是内存碰撞后的堆转储:
EDIT2:这是另一个屏幕截图,其中一些 ZipFileInflaterInputStream 中的 Finalizer 对象占用了大量内存(我不使用它!)
【问题讨论】:
-
进行堆转储以查看当时内存中的内容。
-
我在内存使用转储后使用堆转储编辑了我的原始帖子
-
我发现这只发生在 LocalSessionFactoryBean 作为事务管理器的情况下。使用另一个事务管理器不会导致这种内存碰撞,我猜这与休眠 SessionFactory 使用太多内存有关。
-
刚刚添加了我的堆转储的另一个屏幕截图,其中很多内存被一些 ZipFileInputStream 对象占用!
-
我们很难远程分析这个,你有点靠你自己。您可以使用eclipse.org/mat 之类的工具来提供帮助。如果我是你,我会在之前和之后进行堆转储,然后尝试比较它们,或者使用 eclipse mat 尝试查找一些热点。祝你好运。
标签: java spring hibernate memory