这是通过请求GC执行其活动来避免内存泄漏的最佳方法吗?

时间:2013-06-28 06:09:07

标签: java memory-leaks

在finally块中将实例作为Orphan请求GC以高优先级执行垃圾收集吗?

SQLConnect ds =null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
...  
variables  

try {
    //Business Logic       
} catch(Exception e) {
    //Logging goes here
} finally {
    //Make instances Orphan
    ds = null;
    con = null;
    pstmt = null;
    rs = null;
}

5 个答案:

答案 0 :(得分:10)

没有。你正在做一些毫无意义的事情(当局部变量不再被使用时将其设置为null)但你做一些你应该做的事情:关闭语句/连接。 / p>

您应该在close块中使用finally调用,或者在使用Java 7时使用try-with-resources statement,这样可以简化生活:

try (Connection conn = ...)
{
    try (PreparedStatement statement = ...)
    {
        try (ResultSet rs = ...)
        {
            ...
        }
    }
}

为了垃圾回收而将变量设置为null几乎是不值得的 - 但是在保存非内存资源(文件句柄,网络句柄,数据库句柄等)的实例上调用close是<总是一个好主意。在释放这些资源之前,你真的不想等到终结器为你清理。

答案 1 :(得分:5)

  

在finally块中将实例作为Orphan请求GC以高优先级执行垃圾收集吗?

没有。分配null不会更改对象被垃圾回收的“优先级”。实际上,假设这些变量的范围即将结束,为它们分配null毫无意义。

(将null分配给Java中的某个变量或字段不会减少引用计数等,也不会触发要回收的相应对象。事实上,完全GC是不知道赋值 event 。赋值所做的最多就是尽快使对象无法访问。但是在这个变量即将超出范围的例子中,这种情况几乎会立即发生因此null任务没有达到任何目的。)

当JVM认为这是正确的时间时,垃圾收集将会运行,无论你做什么。除了致电System.gc() ...这是一个非常糟糕的主意for other reasons


在正常情况下,您不必担心GC何时运行。但是,在这种情况下,您正在处理外部资源;即数据库连接,结果集等。这些需要正确“管理”,否则您可能会遇到资源泄漏问题。

如果/当对象确实得到GC时,它们可能会被各自的finalize方法关闭。但是,最终可能会发生太晚以避免资源泄漏的不良后果。

所以管理这些的正确方法不是null他们(徒劳)希望他们能早点进行GC。处理它们的正确方法是在close()块中明确调用各自的finally方法... e.g。

finally {
    conn.close();  // This should also close any child Statement and 
                   // ResultSet instances
}

更好的方法是使用Java 7“尝试使用资源”语法,如Jon Skeet所述。

答案 2 :(得分:1)

请不要弄乱垃圾收集器。这经常导致难以理解但不会提高性能的代码。

只要至少有一个对象的引用,无论你做什么,垃圾收集器都不会收集对象。

如果没有对对象的引用,垃圾收集器将收集该对象。垃圾收集器在内存不足时运行。

请注意,某些对象(例如您的Connection)也是外部资源。必须每次手动释放此资源。因此,关闭Connection块中的finally而不是将其设置为null更为重要。

答案 3 :(得分:1)

java中的内存泄漏与垃圾收集器执行工作的频率或时间无关!

内存泄露,当它永远不会被再次使用且无法释放时。

您的问题可能与资源管理有关。处理数据库连接是管理资源的一个很好的例子,你应该考虑使用某种Connection Pool

旁注:要获取有关内存泄漏在Java中的外观的信息,请访问以下问题:Creating a memory leak with Java

答案 4 :(得分:0)

没有。绝对没有。一千次没有。

Java是一种内存管理语言。尝试强制JVM以与通常管理内存的方式不同的方式管理内存,你自己没有好处。这些方案必须依赖于JVM实现,而不是可移植的,并且可能会导致比修复更多的问题。

避免Java中内存泄漏的最佳方法:

  • 将对象引用限制在最窄的范围内。通常,您将限制对象对单个方法或块的引用范围。一旦引用超出范围,它就有资格进行垃圾收集。

  • 仅针对代表您自己的托管内存实现的引用类型,删除对象引用。在Effective Java,2nd Ed。中,Joshua Bloch给出了一个简单的引用缓存的例子。当缓存收缩时,他建议清空不再使用的引用(否则将保留引用并保持相应的对象不符合收集条件)。他称之为“你选择自己管理的记忆。”

  • 避免将其他短期对象的引用“泄漏”到上下文中,这些引用可以由长期存在的变量持有。内部类表示可能发生这种情况的情况。

  • 为资源密集型的长期对象释放资源。示例是数据库连接和某些GUI控件。

只要您将引用类型限制在最窄的范围内,大多数情况下您永远不必担心垃圾回收。