Чтение изображения с помощью Javax занимает много памяти

#java #swing #javax.imageio

#java — язык #swing #javax.imageio #java

Вопрос:

Я открываю кучу файлов с помощью JFileChooser и для каждого изображения, которое я создаю, BufferedImage используя image = ImageIO.read(path); . Где изображение объявлено как статическое поле.

Теперь у меня есть 30 файлов по 1 Мб каждый, и после запуска 60times read () мое использование памяти (проверено в диспетчере программ OS) увеличивается примерно на 70 МБ.

Поскольку моя переменная image является статической, проблема не в том, что содержимое изображения где-то хранится. Итак, мои вопросы в том, почему я теряю так много памяти?

Я пишу приложение, которому нужно загружать тонны изображений в память, есть ли где-нибудь лук-порей? Является ли задачей сборщика мусора очистка неиспользуемых данных?

Вот мой код для чтения этих данных:

 public class FileListElement {

private static final long serialVersionUID = -274112974687308718L;

private static final int IMAGE_WIDTH = 1280;

// private BufferedImage thumb;
private static BufferedImage image;
private String name;

public FileListElement(File f) throws IllegalImageException {
    // BufferedImage image = null;
    try {
        image = ImageIO.read(f);
        // if (image.getWidth() != 1280 || image.getHeight() != 720) {
        // throw new IllegalImageException();
        // }
    } catch (IOException e) {
        e.printStackTrace();
    }
    image.flush();
    //
    // thumb = scale(image, 128, 72);
    // image = null;

    name = "aa";
}
}
  

Что в этом плохого?

Может быть, я что-то делаю неправильно? Мне нужны необработанные пиксели из тонны изображений или сжатые изображения, загруженные в оперативную память. Чтобы я мог быстро получить доступ к любому пикселю изображения.

Странно, что загрузка изображения размером 1 Мб занимает намного больше, чем 1 Мб.

Комментарии:

1. Добавление к тому, о чем уже упоминал jzd; декодирование изображений из их сжатого / двоичного представления в BufferedImage значительно расширяет данные. Для JPG размером 1 МБ (например) может потребоваться немного больше места в куче для хранения в виде BufferedImage, чтобы вы могли работать с ним.

Ответ №1:

Вы не можете рассчитывать на то, что текущее использование памяти соответствует необходимому объему памяти, сборка мусора выполняется не постоянно, особенно если вы далеки от максимального использования памяти. Попробуйте загрузить больше изображений, возможно, вы обнаружите, что проблемы нет.

Странно, что загрузка изображения размером 1 Мб занимает намного больше, чем 1 МБ.

Ну, я бы ожидал, что формат, хранящийся на диске, возможно, будет сжат / меньше, чем буферизованное изображение в памяти. Так что я не думаю, что это странно.

Комментарии:

1. На самом деле вы были правы. Использование памяти перестает расти на magic 400Mb. Еще один вопрос. Вы имеете в виду, что объект image из ImageIO использует память почти так же, как объект, который будет содержать пиксели изображения raw?

2. @Mikooos: Это не так просто. Например, изображение в формате JPEG может иметь сжатие в диапазоне от 0.0 (несжатое / максимальное качество) до 1.0 (максимальное сжатие / минимальное качество).