SSH整合之 网盘上传下载系统(问题积累)
今天一直在做一个SSH整合的网盘上传下载系统,写一下心得!
首先,我做的的是将上传的文件保存到数据库里面,但是只要上传大于几M以上的文件,就会报
java.lang.OutOfMemoryError: Java heap space
这个异常,后面百度了一下,原来知道数据库里面不能保存过长的二进制文件,所以马上改代码,因为整个项目分层体系很清晰,所以代码修改量很少,呵呵,又一次体验到了分层的好处。
于是,立马想到将上传的文件保存在项目的一个文件夹下面(文件夹任意起名),数据库里面只需要保存上传文件的名字即可,继续,运行,这时上传大一点的文件都没问题,而且速度非常快,于是响应舍友号召,找一部大一点的影片放上去,立马动手,不过结果又悲剧了,又报了
java.lang.OutOfMemoryError: Java heap space
这个异常,继续百度,百度绝大部分答案是说: 在JVM中如果98%的时间是用于GC且可用的 Heap size 不足2%的时候将抛出此异常信息。JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。这个问题的根源是jvm虚拟机的默认Heap大小是64M,可以通过设置其最大和最小值来实现。
于是按照百度的解答,在tomcat里修改了一下JVM的虚拟内存大小。
设置方式有以下几种:
//这是之前的代码,得到输入流,然后写到输出流 InputStream is = new FileInputStream(new File(..)); OutputStream os = new FileOutputStream(new File(...)); int length = is.available(); byte[] buffer = new byte[length]; os.write(buffer); //这是我修改之后的代码 InputStream is = new FileInputStream(new File(..)); OutputStream os = new FileOutputStream(new File(...)); int length = 0; byte[] buffer = new byte[1000]; while(-1 != (length = is.read(buffer, 0, 1000))) { os.write(buffer); }
这时我再试着运行一下,大概过了半分钟,文件上传成功(文件比较大),这时候心里充满了喜悦,我想可能是因为文件太大,如果直接得到文件的大小,然后定义一个该大小的
byte数组,往里面进行I/O操作时因为服务器会响应很久,所以最后报
java.lang.OutOfMemoryError: Java heap space
这个异常,若指定义一个一般大小的byte数组,然后通过while循环的方式,每次读一些,这样对JVM虚拟机内存使用应该会少一些。
最后总的来说,网盘系统上传大型文件报异常这个问题总算解决啦。
(局域网速度还是很快的,10M/s, O(∩_∩)O哈哈~,以后都不需要u盘传东西给他们了,直接打开服务器上传文件,然后下载就行了)