读取大文件时出现Java堆空间错误



我正试图将整个文件作为字符串对象加载到内存中。但在应用程序结束后,我的内存不会被释放回垃圾收集器。我知道读取内存中的整个文件是不好的,但我必须将数据发送到另一个类,有人能帮助我如何将其作为一个流而不是将整个代码加载到内存中吗?如果没有,有人会说我现在的代码出了什么问题吗

private   String processFile(FileItemStream item) throws IOException{
        InputStream is=null;
        try{
            is=item.openStream();
            return IOUtils.toString(is, "UTF-8");
        }
        finally {
            IOUtils.closeQuietly(is);
        }
    }


data=processFile(item)//method call
SomeClass(data);//passing the data string to this class

您应该将is传递到需要数据的类中。只要你不一次把is的所有内容都读进去,你就不会耗尽所有的内存。将您的代码更改为:

InputStream is = null;
try {
    is = getFileAsStream(item);
    SomeClass(is)  //of course this probably doesn't compile, I'm just using your code sample
} finally {
    //close is
}

这取决于您可以使用的API。如果他们的API允许您一次处理数据的字节数组,那么您应该将块读取到缓冲区中并将其发送到该应用程序。如果它允许您传入InputStream,那么您应该这样做。

如果API不允许您执行上述操作之一,那么您唯一可以做的事情就是增加Java可以使用的内存量。为此,使用-Xmx512m开关启动Java,其中512是可以分配给Java的内存量。

如果您真的无法更改您正在调用的API以获取字符串之外的内容,那么您需要通过给JVM更多的内存来解决这个问题。这可以通过向JVM发送一个参数来改变。

-Xmx<size>

例如,您可以使用这样的设置为JVM提供2GB 的最大堆

-Xmx2g

不过,如果您使用的API接受字符串作为参数,并试图传递千兆字节的字符串,则几乎可以肯定,您使用的API不正确。如果有人构建了一个需要大量数据的API,他们不会使用单个字符串作为参数来构建它。祝你好运

相关内容

  • 没有找到相关文章

最新更新