本文介绍了释放java文件句柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个用Java编写的相当大而复杂的应用程序,它运行在Gridgain包之上。我遇到的问题是这个应用程序将在每个请求开始前大约一天处理请求,导致java.nio.channels.ClosedByInterruptException类型的异常。

We have a rather large and complex application written in Java which is running on top of the Gridgain package. The problem I am having is that this application will sit there processing requests for approximately a day before every request starts resulting in an exception of type java.nio.channels.ClosedByInterruptException.

我的假设是应用程序没有释放文件句柄,并且在连续使用一天之后它用完了,无法再继续处理请求(每个请求都需要读取来自每个网格节点的多个文件)。我们已将大部分文件IO操作包装在诸如此类的类中

My supposition is that the application is not releasing file handles and after a day of continuous usage it runs out and can no longer continue to process requests (each request requires the reading of multiple files from each grid node). We have wrapped most of our file IO operations in classes such as this one

package com.vlc.edge;

import com.vlc.common.VlcRuntimeException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public final class BufferedReaderImpl implements BufferedReader {
    private java.io.BufferedReader reader;

    public BufferedReaderImpl(final String source) {
        this(new File(source));
    }

    public BufferedReaderImpl(final File source) {
        try {
            reader = new java.io.BufferedReader(new FileReader(source));
        } catch (FileNotFoundException e) {
            throw new VlcRuntimeException(e);
        }
    }

    public BufferedReaderImpl(final Reader reader) {
        this.reader = new java.io.BufferedReader(reader);
    }

    public String readLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            throw new VlcRuntimeException(e);
        }
    }

    public void close() {
        try {
            reader.close();
        } catch (IOException e) {
            throw new VlcRuntimeException(e);
        }
    }
}

我认为问题在于这个设计没有明确释放文件句柄,我建议的解决方案是添加一个像这样的finalize方法

I think the problem is that this design doesn't explicitly release the file handle, my proposed solution is to add a finalize method like this

    protected void finalize() throws Throwable
    {
        reader.close();
        super.finalize();
    }

将明确地执行此操作。 (最后)的问题是这是否可能产生任何影响。像java.io.BufferedReader这样的类已经有一些处理这类问题的机制吗?

which will do this explicitly. The question (finally) is whether or not this is likely to have any effect. Do classes such as java.io.BufferedReader already have some mechanism for dealing with this type of problem?

编辑:这里也非常感谢检查这是否是实际上是问题...即有没有办法查询正在运行的JVM并询问它的文件句柄分配?

Also greatly appreciated here would be ways of checking whether this is actually the problem... ie is there a way to query a running JVM and ask about it's file handle allocations?

推荐答案

那里重写 finalize()是没有意义的。如果句柄被垃圾收集并最终确定,那么 java.io.BufferedReader 的实例也将被关闭。

There is little point in overriding finalize(). If the handle is getting garbage collected and finalized, then so is the instance of java.io.BufferedReader and it will get closed.

有可能(根据规范)手柄是垃圾收集但未最终确定,但这不太可能。

It is possible (according to the spec) that the handle is being garbage collected but not finalized, but this is not very likely.

你可以试试使用 PhantomReference 来清理未使用的文件句柄,但我的猜测是你的 BufferedReaderImpl 的实例仍在某处引用(例如,从文件名到打开句柄的 Map 中的值),这就是阻止它们被关闭的原因(在这种情况下,终结器将无济于事。)

You could try using PhantomReferences to clean up unused file handles, but my guess is that your instances of BufferedReaderImpl are still referenced from somewhere (e.g. values in a Map from filenames to open handles) and that is what is preventing them from being closed (in which case finalizers will not help.)

这篇关于释放java文件句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 09:48