记一次inputStream.available()的int超长造成的内存溢出

    按字节读取流,byte[] buf = new byte[1024]是固定长度的读取,但是当InputStream 长度超过指定大小的字节后,会造成只读到了一部分,把这个1024换成2024或是更大也只是暂时的。

这时候inputStream.available()这个方法作用就出现了,方法说明是这样的

Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream. The next invocation might be the same thread or another thread. A single read or skip of this many bytes will not block, but may read or skip fewer bytes.

大概的意思是下一次会话会返回一个估计的字节的长度的流,不会阻塞或者跳过,下一次调用可能是同一个线程或另一个线程。一次读取或跳过这么多字节不会阻塞,但可以读取或跳过更少的字节。

问题

一般情况下是可行的

某次下载大文件出现内存异常日志里出现了OutOfMemoryError

Caused by: java.lang.OutOfMemoryError: Requested array size exceeds VM limit

at com.pingan.pilot.spim.manuscript.controller.AttachmentController.downloadZipAttachment(AttachmentController.java:829)

解决办法

错误源头在这:

所以在body=new byte[inputStream.available()]中

inputStream.available()方法返回的是int,而int的长度是32bit,表示数的范围是-2^31到2^31-1

2^31Byte=2*1024*1024*1024Byte=2GB,按字节读取大文件,2G大小就会到达int的最大值,出现OutOfMemoryError

用分块能避免这个问题,且减少内存消耗

byte[] bytes = new byte[2048];

int len;

while ((len = in.read(bytes)) != -1) {

    out.write(bytes, 0, len);

}

你可能感兴趣的:(记一次inputStream.available()的int超长造成的内存溢出)