简体   繁体   English

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

[英]Java heap space error while reading file in byte array

I am getting java out of heap error while using following code. 我在使用以下代码时遇到堆溢出错误。 Can someone tell me what I am doing wrong here ? 有人可以告诉我我在做什么错吗?

On debugging I see taht value of length is 709582875 在调试时,我看到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;
}

The problem is that the byte array you are allocating is too large and it use up the heap space. 问题在于您分配的字节数组太大,并且会耗尽堆空间。

You may try running your program with -Xms and -Xmx option to specify the min and max heap space the java virtual machine uses to run your program. 您可以尝试使用-Xms和-Xmx选项运行程序,以指定Java虚拟机用来运行程序的最小和最大堆空间。

But I suggest you not to read the whole file into a byte array to process it. 但我建议您不要将整个文件读入字节数组进行处理。 you can read part of it into a small byte array, process the portion, and continue to the next part. 您可以将其一部分读入一个小字节数组中,进行处理,然后继续进行下一部分。 This way uses less heap space. 这种方式使用较少的堆空间。

You are consuming 709582875 bytes (about 677MB) at the moment the byte array in the try block is allocated. 在try块中分配字节数组时,您正在消耗709582875字节(约677MB)。 This is quite large by conventional personal computing standards, and would consume most (if not all) of the memory of a JVM started with default settings. 按照传统的个人计算标准,这是非常大的,并且会消耗以默认设置启动的JVM的大部分(如果不是全部)内存。

Some information on default JVM memory settings can be found here 可以在此处找到有关默认JVM内存设置的一些信息。

Try to increase heap size allocated by the Java Virtual Machine (JVM), something like: 尝试增加由Java虚拟机(JVM)分配的堆大小,例如:

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

For example: 例如:
java -Xms64m -Xmx256m HelloWorld

Donot create such a huge byte[] array . 不要创建这么大的byte []数组 Your heap may go out of memory. 您的堆可能内存不足。 It is bad idea to create byte[] array of file length for such a large file. 为这么大的文件创建字节长度的byte []数组是个坏主意。 create small byte array and read the file in chunk by chunk basis 创建一个小字节数组并逐块读取文件

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

Is there a particular reason you nee to read the whole file at once as a byte[]? 您是否有特定的原因需要以字节[]的形式一次读取整个文件? Can you use a memory mapped ByteBuffer instead as this uses very little heap regardless of the size of the file. 您可以使用内存映射的ByteBuffer代替吗,因为无论文件大小如何,它都使用很少的堆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM