Java:OutOfMemory使用Robot#CreateScreateScreenCapture(矩形)

Java:OutOfMemory使用Robot#CreateScreateScreenCapture(矩形),java,collections,awt,out-of-memory,awtrobot,Java,Collections,Awt,Out Of Memory,Awtrobot,我正在编写一个程序,以设定的时间间隔捕获屏幕,当我开始测试时,我发现在它开始捕获图片后,我几乎立即出现OutOfMemoryException。我试着分配更多的内存-我给了它2.56亿,但这几乎没有帮助。它所做的只是让它在抛出异常并再次崩溃之前再持续2到3秒 我知道createScreenCapture(…)方法使用了大量内存,但我看到过一些示例程序,它们可以使用相同的方法记录很长时间——它们是如何做到的 编辑:我已经使用了你们的一些建议,现在我无法摆脱记忆异常!好极了我采取了将照片保存到硬盘的

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

我知道createScreenCapture(…)方法使用了大量内存,但我看到过一些示例程序,它们可以使用相同的方法记录很长时间——它们是如何做到的

编辑:我已经使用了你们的一些建议,现在我无法摆脱记忆异常!好极了我采取了将照片保存到硬盘的方法。然而,实际上,将它们写入归档文件需要相当长的时间。将63帧写入存档文件几乎需要2分钟

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

我见过一些示例程序,它们可以使用相同的方法记录很长时间——它们是如何做到的

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


我是否应该使用特定的程序将其保存到硬盘上?我在考虑将图像转换成int[]数组,然后存储它,因为数组是可序列化的

有许多战略可以实施

  • 将图像转换为无损耗(易于编码)图像格式,并存储图像:
  • 在磁盘上的单独文件中,或
  • 作为(未压缩)Zip存档中的单独条目。通过使用Zip,我们可以绕过报告的存储“数千”个文件的早期问题。出于速度方面的考虑(以及Zip对大多数媒体格式几乎没有作用的事实),请将其解压缩
  • 我曾经在usenet上看到过一段代码,叫做(AFAIR)“Screenies”或类似的东西(现在找不到),它很像你建议的那样。它将原始信息(无任何编码)存储到磁盘上。我尝试了这段代码,没有比将图像编码为PNG和将图像序列化到磁盘更好的性能了。您可能希望运行一些测试,看看哪种方法现在更快

在抓拍下一张图片之前,90毫秒是一个非常短的睡眠时间间隔。你可能吃得太多了。为什么不设置集合的大小限制。

线程。睡眠(90)将使程序暂停90毫秒。因此,在2-3秒内,大约需要200-300张照片,这将是相当多的

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


您当然需要写入磁盘,或者动态压缩数据,但仍然会很容易达到内存限制。

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

        BufferedImage image = robot.createScreenCapture(area); //OutOfMemory on this line.
        collection.addFirst(image);
你能期待什么,你加的越多,它就越大

尝试将其写入文件/数据库或删除较旧的图像缓冲区,以保持可能包含20个最后图像的缓冲区

90毫秒有点短,如果您尝试比较图像,请在添加到集合之前尝试将上一个图像与当前图像进行比较

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

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

因此,与其在程序的生命周期内将图像提交到内存,不如将其保存到硬盘上?“将其保存到硬盘上?”是的。好的,我会研究一下。我是否应该使用特定的程序将其保存到硬盘上?我正在考虑将图像转换为int[]数组,然后存储它,因为数组是可序列化的。^不允许我编辑注释。另外,我应该早点问这个问题——将文件写入硬盘会不会占用大量CPU和内存?我应该将写入操作分离到不同的线程中吗?“将文件写入硬盘不也会占用大量CPU和内存吗?”是的。“我应该把写操作分成不同的线程吗?”很可能。你需要进行实验。通常,我有一个设置,让用户选择每秒有多少张图片。最初我用每秒30帧(FPS)进行测试,几秒钟内内存就用完了,然后我把它设置为每秒5帧,可能一两秒钟后崩溃。我尝试过将速率降低很多,但没有什么帮助。这就是为什么我对此感到惊讶。目前,大家一致认为我需要把它存储在硬盘上。你能告诉我你想要实现什么吗?有很多种方法可以对类别进行蒙皮,本质上是制作一个以视频格式捕获屏幕的工具。拍摄大量图片,然后使用JMF.Ah转换为视频。直截了当地说,试试这个:好吧,那篇帖子说把图片放在一个集合中,这就是我所做的。然而,正如其他人所说,我的内存不足,因为每个图像占用了大量内存。这就是为什么我在寻找替代方案。即使我将图像转换为整数数组并将其写入硬盘驱动器,我也会很快达到极限吗?你以后会怎么处理它们?我想你是想玩点什么?如果您将映像文件写入磁盘,而不是将其保存在集合中,您将受到磁盘大小的限制(每秒35 MB大约为每30秒1GB),因此在500 GB驱动器上可能需要4小时的记录时间。如果你想把它们变成视频,你可以压缩它们,就这样做吧。如果你提到的机器人恰好是Xuggle,看看