問題を解放するC#のピクチャメモリ
-
11-09-2019 - |
質問
私はC#でニュービーです。私は繰り返しワーカースレッドでGUIのピクチャボックスをリフレッシュする必要があります。画像を表示する画像をretrivesのgetImageメソッドとカメラポーリングドライバから取得されます。私は「使用」ディレクティブを使用してビットマップを割り当て、明示的G.Cを呼び出す場合でも、メモリの割り当てが解除されませんしているようです。
ワーカースレッドは次のようなものです。
while (true)
{
// request image with IR signal values (array of UInt16)
image = axLVCam.GetImage(0);
lut = axLVCam.GetLUT(1);
DrawPicture(image, lut);
//GC.Collect();
}
DrawPictureメソッドは、
のようなものですが public void DrawPicture(object image, object lut)
{
[...]
// We have an image - cast it to proper type
System.UInt16[,] im = image as System.UInt16[,];
float[] lutTempConversion = lut as float[];
int lngWidthIrImage = im.GetLength(0);
int lngHeightIrImage = im.GetLength(1);
using (Bitmap bmp = new Bitmap(lngWidthIrImage, lngHeightIrImage)) {
[...many operation on bitmap pixel...]
// Bitmap is ready - update image control
//SetControlPropertyThreadSafe(tempTxtBox, "Text", string.Format("{0:0.#}", lutTempConversion[im[160, 100]]));
//tempTxtBox.Text = string.Format("{0:00000}", im[160, 100]);
//System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
}
}
問題が発生すると、
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
コード行をコメント実際には、ガベージコレクションは、それが同じように動作します。 より良い、問題がとのようです。
System.Drawing.Image.FromHbitmap(bmp.GetHbitmap())
このメモリリークを解決するための任意のアドバイスはありますか?
どうもありがとうございました!
解決
Image
はIDisposable
を実装し、それが不要になったとき、あなたは、あなたが作成した各Dispose
インスタンス上Image
を呼び出すべきではありません。あなたはあなたのコードでは、この行を置き換えるために試みることができる:
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
これによります:
if (pic.Image != null)
{
pic.Image.Dispose();
}
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
この新しいものが割り当てられる前に前の画像を(もしあれば)処分されます。
他のヒント
の事はあなたがGetHbitmap、MSDNによるとbmp
のGDIビットマップを作っている、あります
あなたが呼び出すための責任があります GDI DeleteObjectの解放する方法 GDIビットマップオブジェクトが使用するメモリます。
次にFromHbitmap方法は、GDIビットマップのコピーを作成します。あなたはすぐに新しいイメージを作成した後、GDI DeleteObjectの方法を使用して着信GDIビットマップを解放することができます。
だから、基本的に私が追加することになります:
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
...
IntPtr gdiBitmap = bmp.GetHbitmap();
// Release the copied GDI bitmap
if (pic.Image != null)
{
pic.Image.Dispose();
}
pic.Image = System.Drawing.Image.FromHbitmap(gdiBitmap);
// Release the current GDI bitmap
DeleteObject(gdiBitmap);
あなたはある種の変換を実行するためにGDIビットマップが必要な場合は、私はわかりませんよ。場合は、あなたがちょうどあなたのPictureBoxのImageプロパティにビットマップを割り当て、かつてのソリューションを無視することができません。
// Since we're not using unmanaged resources anymore, explicitly disposing
// the Image only results in more immediate garbage collection, there wouldn't
// actually be a memory leak if you forget to dispose.
if (pic.Image != null)
{
pic.Image.Dispose();
}
pic.Image = bmp;
PBOXから画像を解放するには、いくつかの方法があります。私は強く方法はpbox.Image = Image.FromFile...
を使用していないということですお勧めします。あなたは、FileStreamをを使用していない、あなたはファイル使用Bitmapクラスからそれを読みたい場合。このように:
Bitmap bmp = new Bitmap(fileName);
pbox.Image = bmp; // notice that we used bitmap class to initialize pbox.
...そして、あなたは、画像ファイルbmp.Dispose();
の
をリリースしたいです
今、あなたは、削除、移動したり、ファイルに好きなことができます。