释放java文件句柄

发布于 2024-08-09 02:46:34 字数 1734 浏览 4 评论 0原文

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

我的假设是应用程序没有释放文件句柄,并且在连续使用一天后它会耗尽并且无法再继续处理请求(每个请求需要从每个网格节点读取多个文件)。我们已经将大部分文件 IO 操作包装在这样的类中,

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 方法,

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

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

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

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.

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);
        }
    }
}

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();   
    }

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?

EDIT: 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只为守护你 2024-08-16 02:46:34

不能依赖终结器的调用。这不是资源管理的好方法。 Java 中的标准构造是:

InputStream in = null;
try {
  in = ...;
  // do stuff
} catch (IOException e) {
  // error
} finally {
  if (in != null) { try { in.close(); } catch (Exception e) { } }
  in = null;
}

您可能希望将这些句柄包装在一个类中,但这不是一个可靠的方法。

Finalizers can't be relied on to be called. It's not a good approach for resource management. The standard construct in Java for this is:

InputStream in = null;
try {
  in = ...;
  // do stuff
} catch (IOException e) {
  // error
} finally {
  if (in != null) { try { in.close(); } catch (Exception e) { } }
  in = null;
}

You may want to wrap these handles inside a class but that's not a robust approach.

遗弃M 2024-08-16 02:46:34

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

(根据规范)句柄可能正在被垃圾收集但尚未最终确定,但这不太可能。

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

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.

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.)

红ご颜醉 2024-08-16 02:46:34

Java 规范表示不保证 'finalize()' 会被执行。您的代码必须自己显式关闭 FileReader

Java specification says that it is not guarantee that 'finalize()' will be executed. Your code must explicitly close FileReader yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文