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

问题描述:

在使用以下代码时,我正在从堆错误中获取Java。有人能告诉我我在这里做错了吗?在读取字节数组中的文件时出现Java堆空间错误

在调试我看到长的taht值是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; 
} 
+0

不要将整个文件一次全部读入内存。你应该以大块的方式做到这一点。 – adatapost 2011-12-28 05:12:09

+0

你用小文件试过并验证它工作正常吗? – kosa 2011-12-28 05:18:47

+0

如果'长度 2011-12-28 11:37:33

的问题是,你分配的字节数组太大,它使用了堆空间。

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

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

尝试增加由Java虚拟机(JVM)分配的堆大小, 是这样的:

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

例如:
java -Xms64m -Xmx256m HelloWorld

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

上默认JVM内存设置的一些信息可以发现here

需要一些JVM调整 的java -Xms256m -Xmx1024m

DONOT创建这样的巨大byte []数组。你的堆可能会失去记忆。为这样一个大文件创建文件长度的byte []数组是个坏主意。 创建小字节数组,由大块的基础

读取块的文件是否有你的东东作为一个byte []一次读取整个文件特别的原因?你可以使用内存映射的ByteBuffer来代替,因为无论文件的大小如何,它都会使用很少的堆。