jspsmartupload组件修改经验谈

最近在 JSP 程序开发过程中,发现了很严重的 Java 内存溢出问题。我采用了 Resin 服务器自动重启的方法,临时保证了网站的正常运行。但是我想去寻找问题的症结之所在,我想一定是 JSP 程序或 Java 程序没有及时地释放内存,但到底是哪些类的哪些对象没有被释放?
  
我认真的看了一下 Resin 的错误日志( error.log 文件),发现程序出现 java.lang.OutOfMemoryError 的错误大多情况是在运行一个上传附件的文件时发生的。在这个上传附件的 JSP 文件中,我调用了目前网上很流行的 jspsmartupload 组件,难道是这个组件本身有问题?
  
于是我就下载了一个 Java 反编译工具,把 jspsmartupload 组件的源码文件( class 文件)反编译成 Java 文件。这个组件用到了五个自定义的类,分别是 File 类、 Files 类、 Request 类、 SmartUpload 类和 SmartUploadException 类。里面最核心的方法莫过于 SmartUpload 类的 upload() 方法。我看到 upload 方法中有这样两个语句:
      m_totalBytes = m_request.getContentLength();     (*)
         m_binArray = new byte[m_totalBytes];                    (**)
    
其中,变量 m_totalBytes 表示用户上传的文件(二进制文件)的内容的总长度,我做了一个测试,一个
55.3M
的文件,它的 m_totalBytes
58012662
,显然这是一个很大的数。如果用这样大的数去声明一个 byte 数组,并给数组的每个元素分配内存空间, Java 内存不溢出才怪呢!另外,我发现 SmartUpload 类中的 m_binArray 数组竟然从来没有被释放,难道真的不需要释放吗? JVM 的功能有我们想象的那么强大吗?
    
我对 SmartUpload 类作了如下的改进:
    
1 )对 upload() 方法的 (**) 语句加上了 totalBytes 大小的限制,并加上了 try...catch...finally 去处理异常,如下:
        try{
         if(m_totalBytes>55184652 || m_totalBytes<0)    //55184652
相当于 52.6M
         {
          throw new SmartUploadException("the file is too large to upload.");
         }
         else
         {
                           m_binArray = new byte[m_totalBytes];
                           ......
                }
             catch(Exception e){......}
             catch(Error err){......}
             finally{  m_binArray=null;}
      
这样,就能保证不管用户传的文件是多大,不会出现 java.lang.OutOfMemoryError 的错误,而且如果 upload 失败, m_binArray 所占的内存空间也会被释放。
    
2 )在 SmartUpload 类中增加了一个 stop() 方法,该方法完成的工作就是释放 m_binArray 数组所占的内存空间。代码如下:
     try{
      m_binArray=null; 
     }
     catch(Exception e)
     {
      System.out.println(e.toString()); 
     }
     jspsmartupload
组件就做了这些修改,下面就需要更改调用该组件的 JSP 文件了。其实这个 JSP 文件有一些地方写得不规范。(以下代码中 mySmartUpload 表示 SmartUpload 的一个实例化对象)
    
1 )首先要设置上传附件的 MaxSize
                    mySmartUpload.setTotalMaxFileSize(10240000); //10240000
表示 10M
    
2 )调用 SmartUpload.upload() 方法要捕获一个异常。
              try{
            mySmartUpload.upload();
                    }
                    catch(Exception e)
                   {
               out.print("
文件太大,无法上传 ");
               return;
                   }
    
3 )程序结束时要调用 SmartUpload.stop() 方法。
                  mySmartUpload.stop();
                            mySmartUpload=null;
    
好了,修改完了,把修改后的文件用 Resin 进行测试(操作系统仍然用 Linux9.0 ),程序至今还没有出现 java.lang.OutOfMemoryError 的错误。
    
但愿这种方法能彻底帮我解决问题。当然,还需做进一步测试,看看修改后的组件会不会出现新问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值