Java Servlet文件上传图像-代码是否有效或允许内存泄漏?

Java Servlet文件上传图像-代码是否有效或允许内存泄漏?,java,memory,servlets,image-processing,file-upload,Java,Memory,Servlets,Image Processing,File Upload,我的servlet对通过JSP页面提交供上传的文件执行以下操作 步骤1获取文件,它始终是一个图像 步骤2-检查是否需要调整大小 步骤2a-如果需要调整大小,请执行 步骤3-还可以调整大小并创建缩略图大小 步骤4-将新调整大小的图像存储在服务器上的文件夹中 步骤5将缩略图存储在服务器上的文件夹中 servlet将接受处理的最大图像大小(根据我客户的请求)是3900 x 3900…我知道,这是巨大的!但这正是客户想要的 我已经将servlet放在我的vps上的tomcat上进行测试,我看到一些非常严

我的servlet对通过JSP页面提交供上传的文件执行以下操作

步骤1获取文件,它始终是一个图像
步骤2-检查是否需要调整大小
步骤2a-如果需要调整大小,请执行
步骤3-还可以调整大小并创建缩略图大小
步骤4-将新调整大小的图像存储在服务器上的文件夹中
步骤5将缩略图存储在服务器上的文件夹中

servlet将接受处理的最大图像大小(根据我客户的请求)是3900 x 3900…我知道,这是巨大的!但这正是客户想要的

我已经将servlet放在我的vps上的tomcat上进行测试,我看到一些非常严重的内存消耗

VPS内存限制
我有316MB的内存。在Tomcat上重新启动后,内存大约为108MB。VPS也在运行Apache服务器。
Apache,在Tomcat停止的情况下使用45MB,因此Tomcat在初始启动时占用63MB

Tomcat.conf-文件为堆设置了以下内容

# Initial Java Heap Size (in MB)
wrapper.java.initmemory=100

# Maximum Java Heap Size (in MB)
wrapper.java.maxmemory=128
一旦我运行了图像上传过程——通过JSP页面上的表单提交一个图像文件——servlet就开始执行我上面描述的步骤

我用同样的图像来测试。图像大小为3872x2592像素,相当于2.53MB

我提交这张图片大约5次。每次上传需要一分钟或更长时间才能完成

测试结果 1图像:内存=150mb
2图像:内存=179mb
3图片:179.8
4图片:188.8
5图片:189.3

上传一个只有2.53MB的图像后,为什么会出现这样的跳转? 我不明白。当内存下降时,它会略微下降。我上传了另一张图片,在前5张之后,内存变为188.8

我的代码是否有效率低下的地方?我确保关闭所有流,或者至少我非常确定我关闭了

非常感谢您的任何意见。



我的图像上传和大小调整Servlet
您是否花时间验证了测量的精度?度量值如何反映代码的内存消耗?Java占用的“OS内存”比实际使用的要多,这取决于平台和JVM实现。如果你真的想知道你的代码是否在泄漏内存,你应该尝试一次又一次地调用你的servlet,看看内存占用是否达到OutOfMemoryError。至少25次以上。你对我的代码有什么看法?你有没有看到我可能会把那些不会被垃圾收集的对象放在打开的地方?你可以做得比25个更好。除了向servlet发出额外的请求之外——我的代码看起来怎么样?您是否花时间验证了度量的精度?度量值如何反映代码的内存消耗?Java占用的“OS内存”比实际使用的要多,这取决于平台和JVM实现。如果你真的想知道你的代码是否在泄漏内存,你应该尝试一次又一次地调用你的servlet,看看内存占用是否达到OutOfMemoryError。至少25次以上。你对我的代码有什么看法?你有没有看到我可能会把那些不会被垃圾收集的对象放在打开的地方?你可以做得比25个更好。除了向servlet发出额外请求之外,我的代码看起来怎么样?
public void addPhoto(Statement stmt, HttpServletRequest req, HttpServletResponse res, HttpSession session) {

            BufferedInputStream bis = null; 
            BufferedImage bufimg = null;
            BufferedImage resized = null;
            ByteArrayOutputStream bytestream = null;
            BufferedOutputStream bos = null;
            FileOutputStream fos = null;

    try {

            String ImageMain = "";
            String ImageThumb = "";                

            String dbShortPathMain = "images/gallery/";             
            String dbShortPathThumb = "images/gallery/";                


       String fileNameToLowerCase = "";
       String fileExtension = "";

       byte[] newimage = null;   

       boolean isPart = ServletFileUpload.isMultipartContent(req);

       if(isPart) {


         FileItemFactory factory = new DiskFileItemFactory();

         ServletFileUpload fileupload = new ServletFileUpload(factory);

         java.util.List items = fileupload.parseRequest(req);

         Iterator it = items.iterator();

         while(it.hasNext()) { //while1                                

                FileItem item = (FileItem)it.next();    
                String fieldValue = item.getName(); 

                if(!item.isFormField()) {

                    String fieldName = item.getFieldName();                                             

                    if(fieldName.equals("ImageMain")) { //10

                          //--------------------------
                          //continue processing upload
                          //field wasn't blank
                          //---------------------------
                          // Create a FileItem object to access the file.
                          File f = new File(fieldValue); 

                          // Get content type by filename.
                          String contentType = getServletContext().getMimeType(f.getName());                                  
                            if(contentType == null) contentType = "none";

                    if(!contentType.startsWith("image")) {
                       appendToURL += "&notfile=y";                             
                      } else {
                          //check size                          
                            bis = new BufferedInputStream(item.getInputStream());                       

                            //BufferedImage
                            bufimg = ImageIO.read(bis);                                         

                            //check size of image 
                            int img_width = bufimg.getWidth();
                            int img_height = bufimg.getHeight();

                            //not accepting images larger than 3900 x 3900
                            if(img_width > 3900 || img_height > 3900) { 
                               appendToURL += "&filesize=y";                                
                             } else {                            

                              //------------------------------------------
                              //  R E S I Z E  &   U P L O A D   F I L E 
                              //------------------------------------------
                                //#### STEP 1 - make size (600 max width) image #### 
                                double scale = (double)maxLargeImageSize/(double)img_width;                             

                                Image sized = getScaledInstanceAWT(bufimg, scale, Image.SCALE_SMOOTH);

                                //convert image to BufferedImage
                                resized = toBufferedImage(sized, BufferedImage.TYPE_INT_RGB);                                   

                                bytestream = new ByteArrayOutputStream();       

                                //make file name characters all lowercase, and extract extension (.jpg)
                                fileNameToLowerCase = fieldValue.toLowerCase();                     
                                fileExtension = fileNameToLowerCase.substring(fileNameToLowerCase.indexOf(".")+1,fileNameToLowerCase.length());

                                //initialize buffer output stream for efficiency                 
                                //BufferedOutputStream
                                bos = new BufferedOutputStream(bytestream);

                                //W R I T E image to BufferedOutputStream and ByteArrayOutputStream
                                if(fileExtension.equals("png")) 
                                   ImageIO.write(resized,"png",bos);                             

                                if(fileExtension.equals("jpg"))             
                                   ImageIO.write(resized,"jpg",bos);                             

                                if(fileExtension.equals("jpeg"))                
                                   ImageIO.write(resized,"jpeg",bos);                            

                                if(fileExtension.equals("gif"))
                                   ImageIO.write(resized,"gif",bos);        

                                if(fileExtension.equals("bmp"))
                                   ImageIO.write(resized,"bmp",bos);                                   

                                // Flush ByteArrayOutputStream                              
                                bytestream.flush();         

                                //convert the bytes in stream to byte array
                                //byte[]
                                newimage = bytestream.toByteArray();                                                                            

                                //specify the file name

                                ImageMain = FileUploadPath+"/thenewfile."+fileExtension;
                                dbShortPathMain += cat+"/thenewfile."+fileExtension;

                                fos = new FileOutputStream(ImageMain);              

                                fos.write(newimage);

                                fos.flush();                                    

                                //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                                //#### STEP 2 - make Thumb size (140 max width) image ####
                                scale = (double)maxThumbImageSize/(double)img_height;                               

                                sized = getScaledInstanceAWT(bufimg, scale, Image.SCALE_SMOOTH);

                                //convert image to BufferedImage
                                resized = toBufferedImage(sized, BufferedImage.TYPE_INT_RGB);

                                //used to convert the new image to bytes so it can be put into db
                                //ByteArrayOutputStream
                                bytestream = new ByteArrayOutputStream();                       

                                //initialize buffer output stream for efficiency                 
                                //BufferedOutputStream
                                bos = new BufferedOutputStream(bytestream);

                                //W R I T E image to BufferedOutputStream and ByteArrayOutputStream
                                if(fileExtension.equals("png")) 
                                   ImageIO.write(resized,"png",bos);                             

                                if(fileExtension.equals("jpg"))             
                                   ImageIO.write(resized,"jpg",bos);                             

                                if(fileExtension.equals("jpeg"))                
                                   ImageIO.write(resized,"jpeg",bos);                            

                                if(fileExtension.equals("gif"))
                                   ImageIO.write(resized,"gif",bos);        

                                if(fileExtension.equals("bmp"))
                                   ImageIO.write(resized,"bmp",bos);                                   

                                // Flush ByteArrayOutputStream                              
                                bytestream.flush();         

                                //convert the bytes in stream to byte array
                                //byte[]
                                newimage = bytestream.toByteArray();                                                                            

                                //specify the file name
                                ImageThumb = FileUploadPath+"/newfilethumb."+fileExtension;
                                dbShortPathThumb += cat+"/newfilethumb."+fileExtension;

                                fos = new FileOutputStream(ImageThumb);             

                                fos.write(newimage);

                                fos.flush();                                
                                //#### end large size ####  

                              //---------------------------------------

                        }

                        }                     


                      }                           

                  }//isFormField

                  }//while  

                }//isPart

    }//try
    catch(Exception e) {}

     finally {
    if (bis != null) try { bis.close(); } catch (IOException logOrIgnore) {}
    if (bytestream != null) try { bytestream.close(); } catch (IOException logOrIgnore) {}
    if (bos != null) try { bos.close(); } catch (IOException logOrIgnore) {}
    if (fos != null) try { fos.close(); } catch (IOException logOrIgnore) {}
    }       

}//addPhoto


//-----------------------------------------------------------
//R E S I Z I N G   I M A G E   M E T H O D S
//-----------------------------------------------------------
        public BufferedImage toBufferedImage(Image image, int type) {
            BufferedImage result = null;
            try {
                    int w = image.getWidth(null);
                    int h = image.getHeight(null);
                    result = new BufferedImage(w, h, type);
                    Graphics2D g = result.createGraphics();
                    g.drawImage(image, 0, 0, null);
                    g.dispose();                    
                }//try
                catch(Exception e) {}

                return result;
        }//end

        public Image getScaledInstanceAWT(BufferedImage source, double scale, int hint) {        
            Image newimage = null;
            try {           
                    int w = (int) (source.getWidth() * scale);
                    int h = (int) (source.getHeight() * scale);        
                    newimage = source.getScaledInstance(w, h, hint);
                }//try
                catch(Exception e) {}               

                return newimage;
        }//end