在字节数组中读取文件时出现Java堆空间错误

时间:2011-12-28 05:06:15

标签: java file out-of-memory heap-memory

使用以下代码时,我发现java出于堆错误。有人能告诉我这里我做错了什么吗?

在调试时我看到长度的值是709582875

In main function 

File file = new File(fileLocation+fileName);
if(file.exists()){
s3Client.upload(bucketName,fileName,getBytesFromFile(file));
}


// Returns the contents of the file in a byte array.
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);

// Get the size of the file
long length = file.length();

// You cannot create an array using a long type.
// It needs to be an int type.
// Before converting to an int type, check
// to ensure that file is not larger than Integer.MAX_VALUE.
if (length > Integer.MAX_VALUE) {
// File is too large
log.debug("file is too large"+length);
System.out.println("file is too large"+length);
}

if (length < Integer.MIN_VALUE || length > Integer.MAX_VALUE) {
throw new IOException
(length + " cannot be cast to int without changing its value.");
}

// return "test".getBytes();
// Create the byte array to hold the data

try{
byte[] bytes = new byte[(int)length];
}
catch(OutOfMemoryError e){ System.out.println(e.getStackTrace().toString());}

// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}

// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}

// Close the input stream and return bytes
is.close();
return bytes;
}

6 个答案:

答案 0 :(得分:2)

问题是您分配的字节数组太大而且占用了堆空间。

您可以尝试使用-Xms和-Xmx选项运行程序,以指定java虚拟机用于运行程序的最小和最大堆空间。

但我建议你不要将整个文件读入一个字节数组来处理它。您可以将其中的一部分读入一个小字节数组,处理该部分,然后继续下一部分。这种方式使用较少的堆空间。

答案 1 :(得分:2)

在分配try块中的字节数组时,您正在消耗709582875个字节(大约677MB)。传统的个人计算标准对此非常大,并且会消耗大多数(如果不是全部)JVM以默认设置启动的内存。

可以找到有关默认JVM内存设置的一些信息here

答案 2 :(得分:1)

尝试增加Java虚拟机(JVM)分配的堆大小, 类似的东西:

java -Xms<initial heap size> -Xmx<maximum heap size>

例如:
java -Xms64m -Xmx256m HelloWorld

答案 3 :(得分:1)

不要创建如此庞大的byte []数组。你的堆可能会耗尽内存。为这么大的文件创建文件长度的byte []数组是个坏主意。 创建小字节数组并以块为基础读取块中的文件

答案 4 :(得分:0)

需要一些jvm调优         java -Xms256m -Xmx1024m

答案 5 :(得分:0)

是否有一个特殊的原因需要您将整个文件作为byte []一次读取?您是否可以使用内存映射ByteBuffer,因为无论文件大小如何,它都使用非常少的堆。