使用以下代码时,我发现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;
}
答案 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,因为无论文件大小如何,它都使用非常少的堆。