我在我的 Java 应用程序中遇到内存使用问题,我一直无法理解为什么垃圾收集器没有解决这个问题。代码如下:
public void foo() {
for(int i=0; i<50000; i++) {
bar(i);
}
}
private void bar(int i) {
LargeObject o = new LargeObject();
...
dao.save(o);
}
我的问题是 LargeObject 的实例没有得到垃圾收集 - 为了识别这一点,我使用 jprofiler 进行了概要分析并查看了堆。 LargeObject 实例永远不会被类变量引用,事实上它们不会在 bar()
之外的任何地方被引用。我正在抓紧我的感觉,但这可能与交易开始/结束的地方有关吗?我尝试将 bar()
更改为 public 并使用 Propogation.REQUIRES_NEW
进行注释,并将 foo()
上的注释更改为 Propogation.NEVER
无济于事。
dao 中的代码如下所示:
public void save(LargeObject o) {
hibernateTemplate.getSessionFactory().getCurrentSession().saveOrUpdate(o);
}
垃圾收集肯定会运行,因为我在 jprofiler 中看到它的 Activity 。 foo()
大约需要 30 分钟,bar()
需要 36 毫秒,垃圾收集大约每 60 秒出现一次峰值。
为了回答为什么我确定它们没有被垃圾收集的问题 - 系统中没有任何内容引用 LargeObject 但我看到它们在堆上的实例随着 foo()
的执行而增加。
最佳答案
显然,它们由您的 JPA 提供程序引用(或隐藏在 dao.save()
后面的任何内容)。你确实让引用在外面,因此你失去了对它的控制。无论您是使用私有(private)方法还是公共(public)方法都没有关系。
您可能想分享有关此“DAO”的更多信息。
关于java - 私有(private)方法调用的垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9311877/