Java敲定:即使出现错误,如何释放非GC资源

时间:2014-01-19 09:09:39

标签: java .net

据我所知,无法保证始终调用Object.finalize()。但如果有一个重要的非GC资源,并且用户没有意外调用close(),我该如何释放该资源?

PS。 .NET中的Object.Finalize()是否有同样的问题?如果是这样,那么在这种情况下如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

您应该使用try-finally或更好try-with-resources

try(Resource res = /*aquire resource*/){
//do stuff
}catch(Exception e //or watever){
//handle exceptions
}

以及如何在Java7之前完成它:

Resource res = null;
try{
res = //aquire resource
    //do stuff 
}catch(Exception e /*or whatever*/){
 //handle exceptions
}finally{
    if(null != res){
        res.close();
    }
}

在.Net中你应该使用

using (Resource resource = /*aquire resource*/)
{
    //do stuff
}

简单的答案是YOU CANNOT。这种行为是BUG,您应该找到并修复它。

答案 1 :(得分:1)

.Net有同样的问题,Finalize方法不可靠。因此,在.Net 2.0中解决了这个问题Safe Handles,它提供了一种释放非托管资源的可靠方法。

您所要做的就是从SafeHandleCriticalHandle继承您的课程。这些都确实来自CritialFinializationObject,它变成了可靠性的关键。

详细了解安全手柄here

P.S:这只是部分答案,我是一个.Net的家伙,所以道歉没有java部分答案。

答案 2 :(得分:0)

finalize在.NET中有同样的问题(即如果对象永远不会被垃圾收集,那么将永远不会调用finalize)

在Java中,保证清理的最佳做法是:

final Resource resource = getResource();
try {
    // Do stuff
    ...
} finally {
    resource.dispose();
}

在.NET中,保证清理的最佳做法是:

using (Resource resource = GetResource())
{
    // Do stuff
    ...
}