2011-05-24 142 views
0

在我的程序代码中有很多线程。当我的程序开始并结束时,句柄的数量不会被释放。当程序第二次启动时,手柄的数量增加。每次都发生这种情况。程序的线程数也增加了。任何人都可以告诉我如何释放手柄?因为我的程序存在手柄泄漏问题。如何在java中释放句柄

+2

你是什么意思的“句柄”?你的程序是否优雅地终止?你使用什么物体?通常设置一个对象为'null'将使它成为垃圾收集的候选对象,但是如果你发布了一些相关的代码,它会有所帮助... – mre 2011-05-24 11:48:49

+0

由于代码非常大,它是一个完整的清理项目,所以我认为它不会我可以发布。因此,正如你所说,将它们设置为null将使它们成为垃圾收集的候选对象,但有大量的句柄,所以我使用System.gc(),它不起作用 – 2011-05-24 11:53:47

+0

垃圾收集与文件句柄泄漏很少有关 - 所有的GC都会从内存中删除任何不再被引用的对象。这本质上是Java内部的,并且不会影响外部资源(要注意对象可能有终结器来关闭资源,但这很少见,并且通常被认为是一个坏主意......)。 – 2011-05-24 11:55:55

回答

5

您没有关闭正在使用这些句柄的流。任何时候您使用某种I/O资源时,都需要确保它已关闭。经典则应在finally块来完成,以确保它被称为无论发生什么情况,如:

final FileInputStream in = new FileInputStream("C:/test.txt"); 
try { 
    // Do whatever you want with the stream: 
    // - read from it directly 
    // - call other methods etc. 
    // Just make sure you're really finished with it 
    // by the end of this try block! 
} 
finally { 
    in.close(); 
} 

这同样适用于数据库连接,HTTP连接,各种网址资源 - 用close()方法几乎任何东西。

查看这些实际类型(文件/数据库/网络端口)和任何详细信息(如文件名,远程主机等)将帮助您追踪程序的哪些部分未关闭其资源正确。


这是一个好主意,让try { ... } finally { foo.close(); }成语嵌入到您的编程肌肉记忆,你总是希望处理资源这样的。这是防止泄漏的唯一可靠方法,应该在第一次编写代码时完成,而不是在稍后追查错误时完成。

0

除了Andrzej的说法: 检查您的自定义对象是否覆盖finalize()方法。如果finalize方法抛出异常,那么该对象将永远不会被垃圾收集。

确实需要检查静态集合的用法,通常静态集合是长期存在的。

也许你可以尝试使用软引用和弱引用,以便下次发生垃圾回收时,引用它们的对象可能有资格进行垃圾回收。

再次注意:system.gc()是一个请求,而不是一个强制命令,所以它可能不会产生确切的预期数字。