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 Power Toys 3.5中的 CLR Profiler 分析了我的应用程序。大量内存用于 "NATIVE FUNCTION" / System.Windows.Forms.Control::_InternalWnProc Microsoft.AGL.Common.PAL_ERROR (Microsoft.AGL.Forms.WM int32 int32)。但是,我看不到这些资源在哪里使用。我怎样才能知道?

4

1 回答 1

3
  1. 是的
  2. 我希望(甚至不要试图声称电动玩具分析器会帮助你)

您将不得不检查您的代码。确保对所有 Disposable 对象调用 Dispose,包括所有 GDI 对象、位图、画笔。

其次,如果你曾经调用过 Font.ToHFont,这个调用是非常危险的,因为它需要你 p/invoke DeleteObject 来清理它。(托管调用需要 ap/invoke 不泄漏资源)

我唯一的建议是,出于某种原因,大多数时候我的 AGL 错误发生在问题根源附近。我不记得具体的原因了。在工作中,我们称之为未记录的“加速悲伤层 (AGL)”

最后,我要提出一个更尖锐的问题。您是否一次分配大量位图,然后释放它们,最后尝试创建托管内存对象,也许是缓冲区?Windows Mobile 6 是基于 Windows CE 5.0 而不是 Windows CE 6.0 构建的。因此,每个进程都有 32 MB 的内存限制。如果一次分配大量位图,它们会增加非托管堆的大小。当您处理位图时,会调用 LocalFree 并且堆取消提交但不会释放内存,.NET 将永远不会再看到它。除了避免一次分配大量位图之外,避免这种情况的唯一方法是分配大于或等于 96 KB 的位图,以保留堆外的页面。

可能怀疑这是你的问题,但我会提到它,因为它几乎不可能追踪。但是,我认为在这种情况下您最终会遇到崩溃或 OutOfMemoryException。

无论如何,我会确保您没有泄漏资源或句柄,并仔细检查您的流格式是否正确。

于 2012-11-22T08:05:02.220 回答