java - 私有(private)方法调用的垃圾回收

标签 java memory-management garbage-collection

我在我的 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/

相关文章:

java - 如何在单元测试中模拟 JPA 存储库的查找方法

java - 使用以米为单位的精度作为经纬圆的半径?

c# - .NET 删除父类会将子类变成 "garbage"吗?

java - System.out的实现中不需要捕获异常吗?

Java Security - RSA 公钥和私钥代码问题

c++ - 内存分配错误,可能在 GDB 中

c++ - 我如何限制堆的大小,这样当我分配很多时它不会让机器卡住?

java - 64 位 JVM 上对象引用的内存要求

android - LeakCanary 发现 Android WebView 内存泄漏

java - Spark GC 时间非常长导致任务执行缓慢