即使 BlockingQueue 为空,我的 saveScreenShot 线程也出现 OutOfMemory 错误
在我的 Main 中有以下变量存储图像
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 个消费者线程,唯一的区别是 filePath 不同
// 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()));