Java:OutOfMemory使用Robot #createScreenCapture(Rectangle)

时间:2012-01-08 23:34:52

标签: java collections awt out-of-memory awtrobot

我正在编写一个用于以设定的间隔捕获屏幕的程序,当我开始测试时,我发现在开始捕获图片后几乎立即得到OutOfMemoryException。我尝试分配更多的内存 - 我给它256米,但这几乎没有帮助。它所做的就是让它在抛出异常并再次崩溃之前持续2或3秒钟。

据我所知,createScreenCapture(...)方法使用了大量内存,但我看过可以使用相同方法记录很长时间的示例程序 - 他们是如何做到的?

编辑:我已经使用了你们的一些建议,现在我没有得到OutOfMemoryExceptions!万岁!我采取了将照片保存到硬盘的路线。但是,实际上将它们写入存档文件确实需要很长时间。将63帧写入存档文件大约需要2分钟!

我无法提供任何代码,因为我正在重写I / O部分。致力于改善现状。

5 个答案:

答案 0 :(得分:1)

  

我见过的示例程序可以使用相同的方法记录很长时间 - 他们是如何做到的?

将图像序列化为磁盘(作为单独的文件或单个Zip)。


  

我应该使用某个程序将其保存在硬盘上吗?我正在考虑将图像转换为int []数组,然后只存储它,因为数组是可序列化的。

有许多策略可以追求。

  • 将图像转换为无损(和易编码)图像格式并存储图像:
    1. 在磁盘上的单独文件中,或..
    2. 作为(未压缩的)Zip存档中的单独条目。通过使用Zip,我们可以解决报告存储“数千”文件的早期问题。考虑到速度(以及Zip对大多数媒体格式的影响很小的事实)使其无压缩。
  • 我曾经在usenet上看过被称为(AFAIR)'Screenies'的代码或类似的东西(现在找不到它),这与你建议的非常相似。它将原始信息(没有任何编码)存储到磁盘上。我尝试了代码并且无法获得更好的性能,而不是将图像编码为PNG&将图像序列化到磁盘。您可能希望运行一些测试以查看现在哪种方法更快。

答案 1 :(得分:1)

如何存储图像?你的屏幕有多大?我不熟悉BufferedImage支持的所有ColorModel,但最坏的情况是完整的RGB图像@ 1900 x 1200将是1900 * 1200 * 24位,或大约7 MB。即使是5 FPS,也就是每秒35 MB,在不到10秒的时间内就会溢出256 MB,而忽略了所有其他内存使用情况。

你肯定需要写入磁盘,或者动态压缩这些数据,但你仍然可以很容易地达到内存限制。

答案 2 :(得分:0)

在拍摄下一张照片之前,

90毫秒是一个相当短的睡眠间隔。你可能服用了太多。为什么不设置collection的大小限制。

答案 3 :(得分:0)

Thread.sleep(90)将使程序暂停90毫秒。因此,在2-3秒内,它需要大约200-300个图片,这将是相当多的。

答案 4 :(得分:0)

您正在将图像(区域)的内存添加到集合中。

        BufferedImage image = robot.createScreenCapture(area); //OutOfMemory on this line.
        collection.addFirst(image);

你能期待什么,你添加的越多,它就越大。

尝试将其写入文件/数据库或删除较旧的图像缓冲区以维护大约20张最后图像的缓冲区。

90毫秒有点短,如果您要比较图像,请尝试将之前的图像与当前图像进行比较,然后再添加到集合中。

如果您正在使用网络摄像头进行跟踪类型解决方案,请告诉我们,这是一套全新的工具和概念。