我的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中看到的那样,垃圾收集肯定在运行。
foo()
大约需要30分钟,bar()
大约需要36ms,垃圾收集大约每60秒出现一次峰值。为了回答这个问题,为什么我确定他们没有被垃圾回收-系统中没有任何东西引用LargeObject,但是我看到堆中它们的实例随着
foo()
的执行而增加。 最佳答案
显然,它们是由您的JPA提供程序(或dao.save()
后面隐藏的任何内容)引用的。您确实将引用移到外面,因此失去了对其的控制。是否使用私有/公共方法都无关紧要。
您可能要共享有关此“DAO”的更多信息。