Java: OutOfMemory с использованием Robot # createScreenCapture (Rectangle) - PullRequest
2 голосов
/ 09 января 2012

Я писал программу для захвата экрана с заданным интервалом, и когда я начал тестирование, я обнаружил, что я получаю исключение OutOfMemoryException почти сразу после того, как он начинает захватывать изображения. Я попытался выделить больше памяти - я дал ей 256 м, но это вряд ли помогло. Все, что он сделал, это заставил его продержаться еще 2 или 3 секунды, прежде чем выдать исключение и снова потерпеть крах.

Я понимаю, что метод createScreenCapture (...) использует много памяти, но я видел примеры программ, которые могут записывать в течение длительного времени с использованием одного и того же метода - как они это делают?

Редактировать: я воспользовался некоторыми советами ваших парней, и теперь у меня нет OutOfMemoryExceptions! Ура! Я выбрал путь, который включает в себя сохранение фотографий на жесткий диск. Однако на самом деле их запись в файл архива занимает довольно много времени. Запись 63 кадров в файл архива занимает почти 2 минуты!

Я не могу предоставить код, потому что переписываю часть ввода / вывода. Работаем над улучшением ситуации.

Ответы [ 5 ]

1 голос
/ 09 января 2012

Как хранится изображение? Насколько велик ваш экран? Я не знаком со всеми ColorModel, поддерживаемыми BufferedImage, но в худшем случае полное изображение RGB при 1900 x 1200 будет 1900 *1200* 24 бит или около 7 МБ. Даже при 5 FPS это 35 МБ в секунду, что приведет к переполнению 256 МБ менее чем за 10 секунд, игнорируя все остальное использование памяти.

Вам, безусловно, придется вместо этого записывать на диск или сжимать эти данные на лету, но вы все равно легко достигнете пределов памяти.

1 голос
/ 09 января 2012

Я видел примеры программ, которые могут записывать в течение длительного времени одним и тем же способом - как они это делают?

Сериализация изображений на диск (в виде отдельных файлов или в один Zip).


Есть ли определенная процедура, которую я должен использовать для сохранения на жестком диске? Я думал о том, чтобы преобразовать изображения в массив int [], а затем просто сохранить его, поскольку массивы сериализуемы.

Существует ряд стратегий, которые можно использовать.

  • Преобразование изображения в формат изображения без потерь (и простое кодирование) и сохранение изображения либо:
    1. В отдельных файлах на диске или ..
    2. Как отдельные записи в (несжатом) Zip-архиве. Используя Zip, мы можем обойти ранние проблемы, о которых сообщалось при хранении «тысяч» файлов. Сделайте его несжатым из соображений скорости (и того факта, что Zip делает очень мало для большинства медиаформатов).
  • Однажды я увидел код в usenet, который назывался (AFAIR) 'Screenies' или что-то в этом роде (сейчас не могу его найти), который действительно очень понравился. Он хранит необработанную информацию (без какой-либо кодировки) на диске. Я попробовал код и не смог получить лучшую производительность для него, чем кодирование изображения в PNG и сериализация изображения на диск. Возможно, вы захотите запустить несколько тестов, чтобы увидеть, какой подход выходит быстрее.
0 голосов
/ 09 января 2012

Вы добавляете память изображения (области) в коллекцию.

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

Чего можно ожидать, чем больше вы добавляете, тем больше получаете.

Попробуйте записать его в файл / базу данных или удалите более старый буфер изображений, чтобы сохранить буфер, возможно, из 20 последних изображений.

90 мс немного меньше. Если вы пытаетесь сравнить изображения, попробуйте сравнить предыдущее изображение с текущим, прежде чем добавлять в коллекцию.

Если вы работаете с решениями типа Tracking от веб-камер, сообщите нам, что это целый новый набор инструментов и концепций.

0 голосов
/ 09 января 2012

Thread.sleep (90) заставит вашу программу приостановиться на 90 миллисекунд. Таким образом, через 2-3 секунды, это займет около 200-300 фото, что будет довольно много.

0 голосов
/ 09 января 2012

90 миллисекунд - это довольно короткий интервал сна перед тем, как сделать следующий снимок. Вы, вероятно, принимаете слишком много. Почему бы не установить предел того, насколько большим может стать collection.

...