2013-04-07 723 views
1

我让我的saveScreenShot线程内存溢出错误,即使是BlockingQueue的空内存溢出使用ImageIO.write

在我的主要

存在时,下列变量存储图像

public static BlockingQueue<ImageSaveData> imageQueue1 = new LinkedBlockingQueue<ImageSaveData>(); 
    public static BlockingQueue<ImageSaveData> imageQueue2 = new LinkedBlockingQueue<ImageSaveData>(); 
    public static BlockingQueue<ImageSaveData> imageQueue3 = new LinkedBlockingQueue<ImageSaveData>(); 
    public static BlockingQueue<ImageSaveData> imageQueue4 = new LinkedBlockingQueue<ImageSaveData>(); 

这里是我的ImageSaveData类

import java.awt.image.BufferedImage; 

public class ImageSaveData 
{ 
    private String fileNumber; 
    private BufferedImage image; 

    public ImageSaveData(String fileNumber, BufferedImage image) 
    { 
     this.fileNumber = fileNumber; 
     this.image = image; 
    } 

    public String getFileNumber() 
    { 
     return fileNumber; 
    } 

    public BufferedImage getImage() 
    { 
     return image; 
    } 
} 

这里是我的线程,需要一个屏幕截图并保存它imageQueueX

// long start = System.currentTimeMillis(); 
    synchronized (runner) 
    { 
     int imageCount = 0; 
     int maxCount = 0; 
     boolean hasMessage = false; 
     String[] countFormat = 
     { 
       "00000000", "0000000", "000000", "00000", "0000", "000", "00", "0" 
     }; 
     // 10 
     while (true) 
     { 
      if (maxCount++ < 1000000010) 
      { 
       try 
       { 
        BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); 
        String imageOutNumb = ""; 
        if (imageCount < 10) imageOutNumb = countFormat[0] + imageCount++; 
        else if (imageCount < 100) imageOutNumb = countFormat[1] + imageCount++; 
        else if (imageCount < 1000) imageOutNumb = countFormat[2] + imageCount++; 
        else if (imageCount < 10000) imageOutNumb = countFormat[3] + imageCount++; 
        else if (imageCount < 100000) imageOutNumb = countFormat[4] + imageCount++; 
        else if (imageCount < 1000000) imageOutNumb = countFormat[5] + imageCount++; 
        else if (imageCount < 10000000) imageOutNumb = countFormat[6] + imageCount++; 
        else if (imageCount < 100000000) imageOutNumb = countFormat[7] + imageCount++; 
        else imageOutNumb = "" + imageCount++; 

        ImageSaveData imageSaveData = new ImageSaveData(imageOutNumb, image); 

        while (true) 
        { 
         if (Main.imageQueue1.offer(imageSaveData, 1, TimeUnit.NANOSECONDS)) break; 
         if (Main.imageQueue2.offer(imageSaveData, 1, TimeUnit.NANOSECONDS)) break; 
         if (Main.imageQueue3.offer(imageSaveData, 1, TimeUnit.NANOSECONDS)) break; 
         if (Main.imageQueue4.offer(imageSaveData, 1, TimeUnit.NANOSECONDS)) break; 
        } 
       } 
       catch (HeadlessException | AWTException e) 
       { 
        e.printStackTrace(); 
       } 
       catch (InterruptedException e) 
       { 
        e.printStackTrace(); 
       } 
       catch(OutOfMemoryError e) 
       { 
        try 
        { 
         runner.sleep(1); 
        } 
        catch (InterruptedException e1) 
        { 
         // TODO Auto-generated catch block 
         e1.printStackTrace(); 
        } 
       } 
       try 
       { 
        runner.sleep(34); 
       } 
       catch (InterruptedException e) 
       { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
      else 
      { 
       if (hasMessage) 
       { 
        try 
        { 
         System.out.println(Main.imageQueue1.isEmpty()); 
         System.out.println(Main.imageQueue2.isEmpty()); 
         System.out.println(Main.imageQueue3.isEmpty()); 
         System.out.println(Main.imageQueue4.isEmpty()); 
        } 
        catch (Exception e) 
        { 

        } 
       } 
       else 
       { 
        System.out.println("We Have Finished saving images to memory"); 
        hasMessage = true; 
       } 
      } 
     } 
    } 

我有3个消费者线程的唯一diffrence是,文件路径是不同势

// long start = System.currentTimeMillis(); 
    synchronized (runner) 
    { 
     String PathName = "\\\\DELL\\Maxtor\\aJordan\\"; 
     while (true) 
     { 
      try 
      { 
       ImageSaveData imageData1 = Main.imageQueue1.poll(1, TimeUnit.NANOSECONDS); 
       ImageSaveData imageData2 = Main.imageQueue1.poll(1, TimeUnit.NANOSECONDS); 
       ImageSaveData imageData3 = Main.imageQueue1.poll(1, TimeUnit.NANOSECONDS); 
       ImageSaveData imageData4 = Main.imageQueue1.poll(1, TimeUnit.NANOSECONDS); 
       if (imageData1 != null) ImageIO.write(imageData1.getImage(), "png", new File(PathName + imageData1.getFileNumber() + ".png")); 
       if (imageData2 != null) ImageIO.write(imageData2.getImage(), "png", new File(PathName + imageData2.getFileNumber() + ".png")); 
       if (imageData3 != null) ImageIO.write(imageData3.getImage(), "png", new File(PathName + imageData3.getFileNumber() + ".png")); 
       if (imageData4 != null) ImageIO.write(imageData4.getImage(), "png", new File(PathName + imageData4.getFileNumber() + ".png")); 


      } 
      catch (InterruptedException e) 
      { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      catch (IOException e) 
      { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

错误

java.lang.OutOfMemoryError: Java heap space 
    at sun.awt.windows.WRobotPeer.getRGBPixels(Unknown Source) 
    at java.awt.Robot.createScreenCapture(Unknown Source) 
    at TakeShothandler1.run(TakeShothandler1.java:48) 
    at java.lang.Thread.run(Unknown Source) 

线48

BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); 
+0

请用完全追溯的方式发布完整的错误信息。 – 2013-04-07 04:47:07

+0

确定即时通讯等待它到错误 – JohnM 2013-04-07 04:48:59

+0

@ PM77-1在OP底部添加错误 – JohnM 2013-04-07 05:12:10

回答

1

什么能力你队列和你当前的堆大小?

根据您的分辨率(例如1024x768x32分辨率:1024x768x4bytes /像素= 3.14MB),每个屏幕截图将处于3-10 MB的大概范围内,并且您可能能够以比写入速度更快的速度他们到磁盘。

根据您的堆大小和队列容量,可能不需要很长时间来修剪可用的堆。

而且,我不知道(你可以有其他代码的其他地方),但它看起来像你可能只是轮询从一个队列中的消费者线程:

ImageSaveData imageData1 = Main.imageQueue1.poll(1, TimeUnit.NANOSECONDS); 
ImageSaveData imageData2 = Main.imageQueue1.poll(1, TimeUnit.NANOSECONDS); 
ImageSaveData imageData3 = Main.imageQueue1.poll(1, TimeUnit.NANOSECONDS); 
ImageSaveData imageData4 = Main.imageQueue1.poll(1, TimeUnit.NANOSECONDS); 

编辑:哇,没意识到这个线程已经两岁了。