我的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”的更多信息。

10-02 15:12
查看更多