2011-12-28 28 views
1

在使用以下代碼時,我正在從堆錯誤中獲取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

回答

2

的問題是,你分配的字節數組太大,它使用了堆空間。

您可以嘗試使用-Xms和-Xmx選項運行程序,以指定java虛擬機用來運行程序的最小和最大堆空間。

但我建議你不要將整個文件讀入一個字節數組來處理它。你可以將它的一部分讀入一個小字節數組,處理該部分,並繼續下一部分。這種方式使用更少的堆空間。

1

嘗試增加由Java虛擬機(JVM)分配的堆大小, 是這樣的:

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

例如:
java -Xms64m -Xmx256m HelloWorld

2

你是消費709582875個字節(約677MB)此時分配try塊中的字節數組。這是傳統的個人計算標準相當大的,並且會消耗大多數(如果不是全部的話)以默認設置啓動的JVM的內存。

上默認JVM內存設置的一些信息可以發現here

0

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

1

DONOT創建這樣的巨大byte []數組。你的堆可能會失去記憶。爲這樣一個大文件創建文件長度的byte []數組是個壞主意。 創建小字節數組,由大塊的基礎

0

讀取塊的文件是否有你的東東作爲一個byte []一次讀取整個文件特別的原因?你可以使用內存映射的ByteBuffer來代替,因爲無論文件的大小如何,它都會使用很少的堆。