2 u012161773 u012161773 于 2016.04.23 11:48 提问

javaweb上传文件到本机时,文件一直占用在内存中导致OutOfMemoryError,求前辈指点 5C

下面是上传代码和java内存监视图
以上传一个300M文件大小为示例

 @RequestMapping("/uploads")
    public @ResponseBody String upload(MultipartHttpServletRequest request,
            HttpServletResponse response) throws Exception {
        String result = "";
        // 获取上传的所有文件名
        Iterator<String> itr = request.getFileNames();
        MultipartFile mpf = null;
        while (itr.hasNext()) {
            // 取出文件
            mpf = request.getFile(itr.next());
            try {
                File file = new File(UPLOADFILEPATH);
                if (!file.exists()) {
                    file.mkdirs();
                }
                // 输出(保存)文件
                FileOutputStream fos = new FileOutputStream(new File(UPLOADFILEPATH + mpf.getOriginalFilename()));
                //获取文件的输入流并写入文件
                InputStream fis = mpf.getInputStream();
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = fis.read(buffer)) != -1) {
                    fos.write(buffer, 0, len);
                    fos.flush();
                }
                //关闭流
                fis.close();
                fos.close();
                mpf = null;
                result = "{\"success\":true}";
            } catch (IOException e) {
                result = "{\"success\":false}";
                e.printStackTrace();
            }

        }
        itr = null;
        System.gc();
        return result;
    }

下面是内存监视图
上传前的JvisualVM内存视图
上传前的JvisualVM内存视图
上传后的JvisualVM内存视图
上传后的JvisualVM内存视图
上传后的jconsole内存视图
上传后的jconsole内存视图
上传后的jconsole--old gen内存视图
上传后的jconsole--old gen内存视图
手动执行JvisualVM-GC清理后的内存视图
手动执行JvisualVM-GC清理后的内存视图

大概情况就是这样子了.文件上传本地后,内存一直被占用无法释放,导致内存溢出.困扰我很久了.希望有前辈能指点一下.谢谢!

3个回答

chenhchen1994
chenhchen1994   2016.04.23 12:04

是内存溢出吧 你把虚拟内存值设大一点

chenhchen1994
chenhchen1994 回复Soul柒月: http://blog.csdn.net/chenhchen1994/article/details/51226343 你可以去看看垃圾回收机制
大约 2 年之前 回复
chenhchen1994
chenhchen1994 回复Soul柒月: 你要知道垃圾回收机制,并不是你不用了就直接执行了,只有当该对象不能再被程序中任何一个"活动的部分"所引用,此时才会调用来垃圾回收机制。当然也可以建议JVM执行垃圾回收机制,但不能百分百成功执行。你设置的-Xms512m -Xmx4096m 是在tomcat中设置的吗?
大约 2 年之前 回复
u012161773
u012161773 回复On_the_orad: 我上传完成后使用的堆大小并没有降下来,继续上传使用的堆大小继续增加.然后就OutOfMemory了
大约 2 年之前 回复
u012161773
u012161773 回复On_the_orad: -Xms512m -Xmx4096m这是我设置的.我启动程序后上传几个几百兆的文件后,就报错java.lang.OutOfMemoryError: Java heap space.这让我很不解.我本机物理内存是8G.
大约 2 年之前 回复
chenhchen1994
chenhchen1994 回复Soul柒月: 你可以去看看 这个.http://blog.csdn.net/chenhchen1994/article/details/51219742
大约 2 年之前 回复
chenhchen1994
chenhchen1994 回复Soul柒月: 有自动垃圾回收机制的。。。。。。 你上传JVM的虚拟内存不是指是的文件大小...
大约 2 年之前 回复
u012161773
u012161773 如果占用内存不释放,内存设大一点也有溢出的一天.我只上传了一个300M不到的文件,堆大小暴增了1G左右.
大约 2 年之前 回复
Renfr
Renfr   2016.04.23 15:31

文件读写完成后要及时关闭输入输出流,如果是未关闭输入输出流就会出现该文件正在被其他应用程序占用的现象。可是为什么一会

又可以打开文件了呢,是JAVA自动垃圾回收机制的问题,长时间不用该文件的输入输出流会默认回收掉。上传的文件时同名文件,所以是覆盖的。

在写文件过程中,LED程序已经将其更新状态为1,但是此时输入输出流未关闭,导致LED程序无法访问上传文件。呵呵,到此应该知道怎么解决了。

解决代码:

public void upload() throws Exception{
//以服务器的文件保存地址和源文件名建立上传文件输出流
xczl.setPath(getSavePath()+"\"+getUploadFileName());
FileOutputStream fos = new FileOutputStream(getSavePath()+"\"+getUploadFileName());
//以上传文件创建一个文件上传流
FileInputStream fis = new FileInputStream(upload);
//将上传文件的内容写入服务器
byte[] buffer = new byte[1024*1024];
int len = 0;
while((len = fis.read(buffer))>0)
{
fos.write(buffer,0,len);
}
fos.close();
fis.close();//关键代码
}

如果不行可以看下你的jvm内存设置的大小,建议设大点:
配置缓存步骤:点击 run 进入RunConfigurations 进入arguments 进入VM 在代码最下面添加如下代码:

-Xms512m -Xmx2048m -XX:MaxPermSize=1024m

Apply

u013321534
u013321534   2016.04.24 01:28

试试把fos.flush();去掉

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
上传大文件报内存溢出错误OutOfMemory
最近一个项目要做大的视频文件的上传和下载。本来以前的项目框架里已经有现成的代码了,是用的springMVC文件上传下载的框架,但是以前都传的小文件,没什么问题,这次需要上传大文件,就老是报错了。 搜索原因的时候,发现好像这套框架是网络里面流传得比较广的,也算是bug吧,所以贴出来了。 可惜,看不到上传文件的源码,(因为源码在领导那里,他老人家太忙)。反正最后就是各种折腾,然后找
HttpURLConnection上传大文件内存溢出的原因及解决办法
原因: 由于HttpURLConnection默认是有缓存机制的,在对文件操作时,会将读取的数据写入到缓存区中,并不是直接写入到服务器上,只有当流被关闭时,才将数据提交到服务器上。当缓存区的数据大于虚拟机给点的内存时,就导致内存溢出。 HttpURLConnection设置固定缓存长度的代码: HttpURLConnection设置缓存模式的代码: 解决办法: conn.
Android out of memory 彻底解决Android因加载多个大图引起的OutOfMemoryError,内存溢出的问题
最近因为项目里需求是选择或者拍摄多张照片后,提供滑动预览和上传,很多照片是好几MB一张,因为目前的Android系统对运行的程序都有一定的内存限制,一般是16MB或24MB(视平台而定),不做处理直接加载的话必然会报OOM (Out Of Memmory)。网上有很多解决android加载bitmap内存溢出的方法,我总结了一个通用的方法,下面是我从的开发案例抽取出来的代码: 我在项目中
HttpURLConnection 上传大文件 内存溢出 out of memery
项目中遇到问题总结一下: 在使用HttpURLConnection 上传大文件时,出现内存溢出的错误,这让我产生了错觉,输入和输出流咋会暂用内存,不就是一个数据传送的管道么,都没有把数据读取到内存中,为撒会报错。。。然后就纠结了。。。 不过实在与原来的经验相违背,然后写了一个示例直接从file中读出然后写入到输出流中,发现并没有问题 这下确认了问题出在HttpURLConnection,查看
tensorflow之内存暴涨问题
在用tensorflow实现一些模型的时候,有时候我们在运行程序的时候,会发现程序占用的内存在不断增长。最后内存溢出,程序被kill掉了。 这个问题,其实有两个可能性。一个是比较常见,同时也是很难发现的。这个问题的解决,需要我们知道tensorflow在构图的时候,是没有所谓的临时变量的,只要有operator。那么tensorflow就会在构建的图中增加这个operator所代表的节点。所以,...
困扰我多次的内存溢出问题终于解决了
viewpager+fragment +多图 简直要命,滑动到第10个fragment左右就会内存溢出 说是内存溢出,其实是内存泄漏。图片加载开源库有很多,我用的是Glide,Glide会回收图片释放内存,然而如果该图片一直被imageview保持引用就会出现无法回收的状态,最终这些图片越来越多,导致内存溢出。 然后要解决的问题就是在适当的时间释放掉这些引用。 这里v
linux频繁写文件内存增加的解决办法
最近在做一个采集视频流,直接写文件保存下来的东东。 最开始由于是用ffmpeg写的,没有这个问题,后来修改成直接文件操作写视频数据。 就出来了问题。  具体问题描述:http://blog.csdn.net/yysdsyl/article/details/2453206  大概就是linux 写文件太频繁了,会占用内存一部分作为cache, 以加快读取速度,写的越多,cache就越大,以至于
JVM—内存溢出、OutOfMemoryError、StackOverflowError
学习jvm时看到几篇非常好的系列文章,转载了: 《深入理解Java虚拟机》学习小记一之自动内存管理机制(一) http://my.oschina.net/linuxfelix/blog/128406 一、概要 我们可以带着以下几个问题去学习自动内存管理机制,罗列如下: 什么操作可能导致内存溢出?有哪些种类的内存溢出?都是在内存的哪些区域溢出?
Android使用帧动画内存溢出解决方法
最近在项目遇到的动画效果不好实现,就让UI切成图,采用帧动画实现效果,但是在使用animation-list时,图片也就11张,每张图片大概560k左右,结果内存溢出,崩溃 了,自己用了三张都崩溃;拿代码说; 1.anin_searh.xml <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
ElasticSearch——Java 内存溢出
Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结 java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产生该错误的原因大都出于以下原因:JVM内存过小、程序不严密,产生了过多的垃圾。 导致OutOfMemoryError异常的常见原因有以下几种: 内存中加载的数据量过于庞大,如一次从数据库取