4

メモリリークに問題があります。

私はこのコードをに持っていますbutton_click

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

    Dim ms As New IO.MemoryStream
    Dim bm As New Bitmap("\Application Data\imgs\IMG22.jpg")
    bm.Save(ms, Drawing.Imaging.ImageFormat.Jpeg)
End Sub

このコードは、ラップトップで .exe を実行している場合 (完全な .net フレームワークを備えた windows7/32 ビットを意味します) は問題なく動作しますが、WindowsMo​​bile 6.1 を搭載したデバイスでアプリを実行すると、アプリは次の例外をスローします。

SmartDeviceProject22.exe
OutOfMemoryException

Microsoft.AGL.Common.MISC.HandleAr(PAL_ERROR ar)
at
System.Drawing.Image.Save(Stream stream, ImageFormat format)
at
SmartDeviceProject22.Form1.Button3_Click(Object sender, EventArgs e)
at
....

画像サイズは約 200kb、幅と高さは約 1500px です。画像の詳細:

  • 寸法: 1536x2048
  • 水平解像度: 72dpi
  • 水平解像度: 72dpi
  • ビット深度: 24
  • 解像度単位: 2
  • 色表現:sRGB -

どんな助けでも本当に感謝します。

@asawyer のコードを試しても、すべてのコード、参照などを削除しても問題は解決しません。画像の幅/高さ、またはコンパクトなフレームワークに関するものだと思います。

他にアドバイスはありますか?

問題の解決策と説明 @pdriegenが言ったように、実際の問題をテストした後、メモリリークではありませんでした。

コードを次のように変更します (モバイル デバイスでテストします)。

 Dim fs As IO.FileStream = IO.File.OpenRead("\Application Data\ryder\IMG23.jpg")
 Dim arrb(fs.Length) As Byte     
 fs.Read(arrb, 0, arrb.Length)
 fs.Close()
 fs.Dispose()

上記のコードでは (どうやら)、dataSet を使用してデータベースに格納する画像の byte() (配列) を取得します。

結論として、bitmap オブジェクトを memoryStream にロードするのは悪い考えです。私の問題を読んでくれた人、特に回答を投稿してくれた人に感謝します。

解決策 (画像ボックスに画像を表示する必要がある場合):

数週間後、これがおそらく最良の (無料の) ソリューションです: ここで説明されているように ImageHelper を実装します: ImageHelper

ImageHelper への更新されたリンク https://opennetcf.com/2010/10/13/loading-parts-of-large-images-in-the-compact-framework/

このクラス/サンプルは、OpenNetCF ( http://www.opennetcf.com/ )の Drawing NameSpace を使用します。

それはうまく機能し、大きなビットマップをメモリにロードする際のメモリの問題を解決します。実際にはサムネイルをロードするため、メモリのサイズが大幅に削減され、OutOfMemory 例外の問題が回避されます。

Chris Tacke について ImageHelper に関する投稿の著者であり、OpenNetCF の共同創設者であることに気付きました。彼のプロフィールはhttps://stackoverflow.com/users/13154/ctackeにあります。

更新されたリンク https://opennetcf.com/2010/10/13/loading-parts-of-large-images-in-the-compact-framework/

4

2 に答える 2

5

問題はメモリリークではないと思います。代わりに、問題は使用可能なメモリの不足です。

圧縮された画像のサイズは 200kb ですが、ビットマップとしてロードすると、解凍されてネイティブのビットマップ形式でメモリに格納されます。高さと幅がそれぞれ 1500px で、ビットマップ形式が 32bpp (指定されていない場合のデフォルト) であると仮定すると、割り当てられたメモリは 9MB になります。

1500 * 1500 * 4 = 9MB。

モバイル デバイスの OS に存在するメモリの制約 (32MB/プロセス - システム dll によって割り当てられるスペース) を考えると、メモリ不足のシナリオになる可能性があります。もちろん、このコードを実行しているアプリケーションによって他のどのメモリが割り当てられているかはわかりません。

小さい画像を使用して、同じデバイスで同じコードを試してください。正常に実行されることがわかるはずです。

于 2012-06-14T15:44:33.137 に答える
1

リークしている Gdi ハンドル、ストリームとビットマップをUsing句でラップします。

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

    using ms As New IO.MemoryStream
        using bm As New Bitmap("\Application Data\imgs\IMG22.jpg")
            bm.Save(ms, Drawing.Imaging.ImageFormat.Jpeg)
        end using
    end using

End Sub
于 2012-06-14T13:32:04.927 に答える