2012-01-24 6 views
3

実行時にデスクトップアプリケーションでパネルにイメージ(各サイズは(40〜100 KB)です)を追加します。最初に、ユーザーはすべての画像をブラウズし、それらをパネル上にロードする。画像が次々にロードされると、タスクマネージャに表示されるメモリ使用量が急速に増加し、一定数の画像の後に「メモリ不足例外」が表示されます。私のコードのどこに欠陥がありますか?メモリ不足の例外なしでC#で1000個の画像をロード

700画像を読み込む前に、タスクマネージャーに1.05 GBというメモリ使用量が表示されます。タスクマネージャをロードした後 は2.04ギガバイトおよび2 GBのRAMが

int picnumber = 0; 
     int numberOfImages = 12; 

     numberOfImages = Convert.ToInt32(textBox1.Text.ToString()); 

     for (int i = 0; i < numberOfImages; i++) 
     { 
      GroupBox gBox = new GroupBox(); 

      picnumber++; 


      //////////////////////////////// 

      // calculate the position of the groupbox where it is placed. 
      if ((picnumber % 3) == 1) 
      { 
       x = initX; 
      } 
      else 
      { 
       if ((picnumber % 3) == 0) 
       { 
        x = initX + 2 * (130 + 20); 
       } 
       else 
       { 
        x = initX + 130 + 20; 
       } 

      } 
      /////////////////////////////////// 


      System.Drawing.Point CurrentPoint; 

      CurrentPoint = panel1.AutoScrollPosition; 
      y = initY + ((picnumber - 1)/3) * (130 + 20) - (Math.Abs(panel1.AutoScrollPosition.Y)); 

      gBox.Text = picnumber.ToString(); 

      //place the groupbox in the appropriate position. 
      gBox.Location = new System.Drawing.Point(x, y); 
      gBox.Size = new System.Drawing.Size(130, 130); 

      Bitmap btmap = new Bitmap(@"E:\43.jpg"); 
      // attach the image to the groupbox 
      gBox.BackgroundImage = btmap; 
      **gBox.BackgroundImageLayout = ImageLayout.Stretch; 
      // add the groupbox that contains image to the panel. 
      panel1.Controls.Add(gBox);** 

をオーバーフローしかし、私は例えば、「バッチ画像リサイズ、画像の膨大な数を読み込むことができますいくつかのアプリケーションを見て無視できるメモリを要するている示してい"(http://www.jklnsoft.com/

アプリケーションはどのようにメモリを処理しますか?彼らはどのような仕組みですか?

700イメージをロードする前に、タスクマネージャは1.05 GBのメモリ使用量を示します。タスクマネージャをロードした後 は1.06ギガバイト

開発環境を示しています。 C#.NETのフレームワーク4、 のWindows XP、 のVisual Studio 2010を、 RAM:2ギガバイト

+1

「ビットマップ」が削除されていないと思うので、この投稿はhttp:// stackoverflowに役立ちます。com/questions/2808753/right-way-to-dispose-image-bitmap-and-picturebox – V4Vendetta

+0

これらの画像をロードする前に、アプリで1GBを使用しますか? –

+0

私はuser1118321の答えを使用して、Chris Healdの答えと組み合わせて、あなたにうまく役立つと思います。 –

答えて

7

それは100キロバイトのJPGを取ることに注意することが重要ですロットは100kb以上のメモリを搭載しています。 100KBは、ディスク上のデータの圧縮サイズです。 800x600の32ビット(イメージ情報のピクセルあたり4バイトを意味する)イメージを持っている場合は、ディスク上で100kbであるかもしれませんが、解凍してメモリに保存して、800 * 600 * 4 = 1,920,000バイト= 1.83MBのRAM。 1.83 * 700 =すべての画像を保持するために1,281MBのRAMが使用されています。

解決策は、イメージを読み込んでメモリのサムネイルを小さくし、メモリから元のイメージを破棄することです。あなたの800x600が80x60 @ 16ビットのサムネイルを持っている場合、それは表示するために9.3kbのRAMしかかかりません。それらのうち700個は6.5MBのRAMしか消費しません。

3

ビットマップのようなリソースは、使用後に処分する必要があります。

using(Bitmap btmap = new Bitmap("E:\etc...")) { 
    ... code here 
} 

すべてのリソースをループした後ではなく、各繰り返しでこれを実行してください。

5

オンデマンドでロードしてキャッシュしたいと思うでしょう。つまり、ウィンドウに20枚の写真が表示されている場合は、現在の位置の前に10、現在の位置に20の写真が表示されます。ユーザーがスクロールすると、開始位置を超えてスクロールしたものをスローし、すぐに表示されるものをスローすることができます。このようにして、あなたはたった数回だけ記憶に残っています。

0

CacheOptionを使用してください。

public static ImageSource BitmapFromUri(Uri source) 
{ 
    var bitmap = new BitmapImage(); 
    bitmap.BeginInit(); 
    bitmap.UriSource = source; 
    bitmap.CacheOption = BitmapCacheOption.OnLoad; 
    bitmap.EndInit(); 
    return bitmap; 
}