0

私のプログラムでは、ハード ドライブに保存されている特定の数の画像にアクセスする必要があります。本当に必要になったときにのみロードするか、起動時にすべてロードすることができます。

好奇心から、いくつかのフォルダーからすべて (約 11k) の画像を読み取り、それらをいくつかのリストに保存しようとしました。これには時間がかかりすぎるのではないかと思っていましたが、約 9k の画像を読み込んだ後に OutOfMemoryError を受け取りました。

JRE のヒープ サイズは 1g (-Xmx1g) です。

私のコードでこれが起こるのはなぜですか? メモリリークが発生していますか? これをもう経験しないために何を変更すればよいか、またはファイルが必要になったらファイルのみを読み取るだけの解決策はありますか? すべてのファイルの全体のサイズは 40 MB 程度しかないので、メモリに保持しても問題ないと思いました (1g のヒープ サイズから見て 40 MB は大きすぎないようです)。または、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;
    }

}

毎度お返事ありがとうございます。

4

1 に答える 1

2

すべてのファイルの全体的なサイズはわずか約 40 MB です...

しかし、画像ファイルをメモリにロードすると、画像は解凍され、ピクセルの配列に変わります。元の画像ファイル形式 (および圧縮パラメーター) によっては、1以上のヒープ領域が必要になる場合があります。

何を達成しようとしているのかは完全には明らかではありませんが、実際に使用するときにのみこれらの画像をメモリにキャッシュすることを検討する必要があります。

于 2013-07-14T16:25:08.263 に答える