4

私のアプリケーションは、基本的に写真ブラウザです。私のアプローチ(私を判断しないでください、私はJavaが初めてです)は、画像をArrayListいっぱいにしてから(左側に)BufferedImages追加することでした。JList

これは私が画像を取得する方法です:

private void getFullImage() {

        BufferedImage im = null;        


        ImageReader imageReader = null;
            try {
                System.out.println("Loading "+original+"...");
                String suffix = Utils.getFileExt(original.getName(), "jpg");
                @SuppressWarnings("rawtypes")
                Iterator readers = ImageIO.getImageReadersBySuffix(suffix);
                imageReader = (ImageReader)readers.next();
                imageReader.setInput(new FileImageInputStream(original));
                im = imageReader.read(0);
                imageReader.dispose();
            } catch (Exception e)
            {
                e.printStackTrace();
            }

        this.img = im;
    }

そして、すべてのデータをフェッチした後、画像を my に追加しますJList

   Vector vector = new Vector();
   JPanel container = null;
   PhotoPanel pp = null;
   Photo p = null;
   for(int i=0;i<files.length;i++)
   {
        p = new Photo(files[i]);
        pp = new PhotoPanel(p);
        container = new JPanel(new BorderLayout());
        container.add(pp,BorderLayout.CENTER);
                                       container.setBorder(BorderFactory.createTitledBorder(p.getTitle()));
                                vector.addElement(container);
  }
   plist.setListData(vector);

たとえば、10 個のファイルがある場合、アプリはかなりうまく機能します。問題は、表示する画像がたくさんある場合です。次に、例外が発生しますException in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space。したがって、私のアプローチが非常に貧弱であることはわかっており、すべての画像をどのように取得して保存し、JList. たぶんキャッシュメモリを使用していますか?何かを読んだSoftReferenceが、使い方がよくわからない。ありがとう。

4

2 に答える 2

5

この問題の主な原因は2つあります。


1つ目は、実際の原因としてではなく警告として投稿していることですが、コンソールに。を使用して過剰な量のデータが印刷されているということSystem.out.println()です。

NetBeansでのみ発生するのか、すべての開発ツールでのみ発生するのかわかりません。しかし、いずれにせよ、それをトリガーするためには本当にばかげた量の印刷が必要であり、あなたがそれほど多くのファイルをロードしているとは思えません。

とにかく、このSystem.out.println("Loading "+original+"...");行の目的が、開発/デバッグの目的で一時的にコードに追加したものではなく、永続的な/本番環境のログ記録である場合は、適切なを使用することをお勧めしますLoggerこのSO回答のTL;DRバージョンの手順を読むことができます。また、そこに提供されているリンクから、公式ドキュメントを含め、さらに読むことができます。


もう1つの原因は、間違いなくあなたのものですが、同時にロードされているデータが多すぎることです。解決策は次のいずれかです。

  1. 画像を縮小して(サムネイルを作成)、選択した画像のフルサイズバージョンのみを表示します。これは迅速な解決方法であり、推奨されないことに注意してください。それでもシステムが耐えられないかもしれないので。
  2. インターフェイスの表示部分に存在する画像のみをロードし(または、組み合わせた最良のソリューションの場合は、上記の画像のサムネイル)、インターフェイスをナビゲートするときに新しい画像をロードします(そして他の画像をアンロードします)。
于 2012-04-16T13:20:19.887 に答える
0

私は大きな画像 (SWT で) に苦労していましたが、OutOfMemory と NoMoreHandles (十分なメモリがない場合でも発生する可能性があります) は悪夢でした。大きな画像を保持したり、大量の画像をメモリに保持したりする方法はないと思います。アンドリューのコメントに同意しますが、要件に応じて、キャンバス(またはSwingにあるもの)を拡張して、メモリに保持せずに画像を直接描画できることを追加したかっただけです(PaperClips#と同様)印刷プレビュー)。確かに、画像を正しくレイアウトするにはいくつかの計算が必要になりますが、この場合、メモリの問題を克服できると思います (ただし、他の問題がいくつか発生します:))

于 2012-04-16T13:45:57.320 に答える