2013-04-07 719 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); 

編輯:哇,沒意識到這個線程已經兩歲了。