У меня есть ситуация в моей программе, когда мне нужно получить доступ к определенному количеству изображений, сохраненных на моем жестком диске. Я мог либо загружать их только тогда, когда они мне действительно нужны, либо загружать их все уже при запуске.
Из любопытства я попытался прочитать все (около 11 тысяч) изображений из нескольких папок и сохранить их в нескольких списках. Мне было интересно, занимает ли это слишком много времени, но я получил OutOfMemoryError после чтения около ~ 9 тыс. изображений.
Моя JRE имеет размер кучи 1g (-Xmx1g).
Почему это происходит для моего кода? Я создаю утечку памяти? Есть ли у вас какие-либо предложения, что изменить, чтобы больше не испытывать этого, или решение просто читать только файлы, как только они мне понадобятся? Общий размер всех файлов составляет всего около 40 МБ, поэтому я подумал, что будет нормально хранить их в памяти (40 МБ, похоже, не слишком много для моего размера кучи в 1 г). Или java выполняет какие-то сумасшедшие волшебные вещи, умножая размер файла на большие числа после загрузки?
Я провел некоторое исследование stackoverflow, но не смог преобразовать данные ответы (например, из здесь или здесь) для моего случая. Так что, если у кого-то из вас есть идеи, я был бы очень рад :)
Мой код здесь, извините, если он немного некрасивый - я просто бездельничал:
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
public class FatfontsManager {
private List<BufferedImage> until9;
private List<BufferedImage> until99;
private List<BufferedImage> until999;
private List<BufferedImage> until9999;
// loads and keeps all images
public FatfontsManager() {
until9 = new ArrayList<>();
until99 = new ArrayList<>();
until999 = new ArrayList<>();
until9999 = new ArrayList<>();
String absolutPathToThisProject = new java.io.File("")
.getAbsolutePath();
// load Images
for (int i = 1; i < 10; i++) {
until9.add(loadImage(absolutPathToThisProject
+ "\\latexDir\\0..9\\" + i + ".png"));
}
System.out.println("1 - 9 loaded");
for (int i = 1; i < 100; i++) {
until99.add(loadImage(absolutPathToThisProject
+ "\\latexDir\\0..99\\" + i + ".png"));
}
System.out.println("1 - 99 loaded");
for (int i = 1; i < 1000; i++) {
until999.add(loadImage(absolutPathToThisProject
+ "\\latexDir\\0..999\\" + i + ".png"));
}
System.out.println("1 - 999 loaded");
for (int i = 1; i < 10000; i++) {
until9999.add(loadImage(absolutPathToThisProject
+ "\\latexDir\\0..9999\\" + i + ".png"));
}
System.out.println("1 - 9999 loaded");
}
public static void main(String[] args) {
new FatfontsManager();
}
public static BufferedImage loadImage(String ref) {
BufferedImage bimg = null;
try {
bimg = ImageIO.read(new File(ref));
} catch (Exception e) {
System.err.println("Error loading image file " + ref);
e.printStackTrace();
}
return bimg;
}
}
Большое спасибо за каждый ответ.