4

.NET Compact Framework 3.5プロジェクト(Windows Mobile 6で実行)にリソースをロードすると、TargetInvocationExceptionがランダムに発生します。これらは、次のスタックトレースに似ています。

FATAL 2012-11-13 14:17:00,657 [23768895] TargetInvocationException - mobileX.MIP.Post.Presentation.Program
System.Reflection.TargetInvocationException: TargetInvocationException ---> System.Exception: Exception
at Microsoft.AGL.Common.MISC.HandleAr(PAL_ERROR ar)
at System.Drawing.Bitmap._InitFromMemoryStream(MemoryStream mstream)
at System.Drawing.Bitmap..ctor(Stream stream)
at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstructorInfo rtci, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
at System.Resources.ResourceReader.CreateResource(Type objType, Type[] ctorParamTypes, Object[] ctorParameters)
at System.Resources.ResourceReader.LoadBitmap(Int32 typeIndex)
at System.Resources.ResourceReader.LoadObjectV2(Int32 pos, ResourceTypeCode& typeCode)
at System.Resources.ResourceReader.LoadObject(Int32 pos, ResourceTypeCode& typeCode)
at System.Resources.RuntimeResourceSet.GetObject(String key, Boolean ignoreCase)
at System.Resources.ResourceManager.GetObject(String name, CultureInfo culture)

この例外の理由についての私の推測は、クリーンアップするのを忘れた管理されていないリソースがあるということです。ただし、プロジェクトには多くのフォームとリソースがあります。

だからここに私の質問があります:

  1. クリーンアップされていないフォームまたはリソースがこの例外の理由である可能性がありますか?
  2. メモリを浪費する正確なフォームまたはリソースを追跡するにはどうすればよいですか?

2について: .NET Compact Framework PowerToys3.5のCLRProfilerを使用してアプリケーションのプロファイルを作成しました。たくさんのメモリが「NATIVEFUNCTION」/に行きSystem.Windows.Forms.Control::_InternalWnProc Microsoft.AGL.Common.PAL_ERROR (Microsoft.AGL.Forms.WM int32 int32)ます。ただし、これらのリソースがどこで使用されているかはわかりません。どうすればわかりますか?

4

1 に答える 1

3
  1. はい
  2. 私は願っています(そして、パワートイプロファイラーがあなたを助けると主張しようとさえしないでください)

コードを確認する必要があります。すべての GDI オブジェクト、ビットマップ、ブラシを含むすべての Disposable オブジェクトで Dispose を呼び出していることを確認してください。

第 2 に、Font.ToHFont を呼び出した場合、この呼び出しは非常に危険です。これは、後でクリーンアップするために DeleteObject を p/invoke する必要があるためです。(管理された呼び出しでは、リソースをリークしないように ap/invoke が必要です)

私の唯一のアドバイスは、何らかの理由で、ほとんどの場合、AGL エラーは問題の原因の近くで発生するということです。具体的な原因は思い出せません。職場では、これを文書化されていない「Accelerated Grief Layer (AGL)」と呼んでいます

最後に、もう 1 つ鋭い質問があります。大量のビットマップを一度に割り当ててから解放し、最後にマネージ メモリ オブジェクト (おそらくバッファ) を作成しようとしていますか? Windows Mobile 6 は、Windows CE 6.0 ではなく、Windows CE 5.0 から構築されています。したがって、各プロセスには 32 MB のメモリ制限があります。一度に多数のビットマップを割り当てると、アンマネージ ヒープのサイズが大きくなります。ビットマップを破棄すると、LocalFree が呼び出され、ヒープはデコミットされますが、メモリは解放されず、.NET はそれを再び見ることはありません。一度に大量のビットマップを割り当てることを避ける以外に、これを回避する唯一の方法は、ヒープ外のページを予約する 96 KB 以上のビットマップを割り当てることです。

おそらくそれがあなたの問題であるとは思えませんが、追跡することはほとんど不可能であるため、言及します. ただし、その場合、クラッシュまたは OutOfMemoryException が発生すると思います。

とにかく、リソースやハンドルがリークしていないことを確認し、ストリームが正しい形式であることを再確認します。

于 2012-11-22T08:05:02.220 に答える