美文网首页生活、程序、健身程序员
剖析WorkflowFoundation的内存泄漏问题

剖析WorkflowFoundation的内存泄漏问题

作者: Statham_Jessie | 来源:发表于2019-12-30 15:27 被阅读0次

        最近项目在使用微软的WorkflowFoundation框架进行流程开发,在使用WorkflowDesigner的时候,会发生内存和句柄泄漏的现象。开始泄漏分析:

        句柄泄漏使用微软的 handle.exe,https://technet.microsoft.com/en-us/sysinternals/bb896655.aspx,将handle.exe放到c:\\windows\system32下。快捷键windows+r运行cmd命令,输入handle -p [processname] -s;发现etwregistration句柄在不断增长,经过对源码进行分析,发现在调用WorkflowDesigner的Load(object obj)方法时,创建了EventProvider,继承了IDisposable接口。在销毁所有的服务的时候并没有对这个非托管资源进行销毁,进而导致句柄泄漏。这里说一句,windows程序都会有一个最大句柄数,一但超过这个最大数,应用就会报错。由于EventProvider是被包装成private的成员变量,所以只能通过反射的方式去释放资源。

void CloseDesigner(WorkflowDesigner designer)

        {

            if (designer == null)

                return;                        

                var service = designer.Context.Services;

                var serviceType = service.GetType();

                var subservice = serviceType.GetField("_subscriptions",System.Reflection.BindingFlags.IgnoreCase| System.Reflection.BindingFlags.Instance| System.Reflection.BindingFlags.NonPublic);

                if (subservice != null)

                {

                    var subserviceFiled= subservice.GetValue(service);

                    var kv = subserviceFiled as Dictionary<Type, SubscribeServiceCallback>;

                    if (kv != null)

                    {

                        Dictionary<Type, SubscribeServiceCallback> cache = new Dictionary<Type, SubscribeServiceCallback>();

                        foreach (var item in kv)

                        {

                            cache.Add(item.Key,item

                                .Value);

                        }

                        foreach (var item in cache)

                        {

                            service.Unsubscribe(item.Key, item.Value);

                        }

                        cache.Clear();

                    }

                }

                var services = serviceType.GetField("_services", System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

                if (services != null)

                {

                    var servicesField = services.GetValue(service);

                    var kv = servicesField as Dictionary<Type, object>;

                    if (kv != null)

                    {

                        foreach (var item in kv)

                        {

                            var keyType = item.Key;

                            if (keyType.Name == "DesignerPerfEventProvider")

                            {

                                var instance = item.Value;

                                var provider = keyType.GetField("provider", System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

                                if (provider != null)

                                {

                                    var providerField= provider.GetValue(instance);

                                    EventProvider eventProvider = providerField as EventProvider;

                                    eventProvider?.Dispose();

                                    eventProvider = null;

                                }

                                break;

                            }

                        }

                    }

                }

                designer.Context.Dispose();

                designer.ContextMenu?.Items.Clear();

                designer.View?.CommandBindings?.Clear();

                designer = null;

        }

    分析应用内存,使用vs的工具快照进行分析,经过分析比对。DesignerView这个对象的引用一直没有得到释放,经过对源码进行剖析。发现内部有大量的委托事件未得到释放,这是一个挺巨大的工程,释放了部分事件后,泄漏有所减轻,要想彻底的解决还需要在花精力进行分析。暂时只能先解决到这个层面,希望感兴趣的同学能够对这个问题进行深入研究。也希望微软能解决这个bug。

相关文章

  • 剖析WorkflowFoundation的内存泄漏问题

    最近项目在使用微软的WorkflowFoundation框架进行流程开发,在使用WorkflowDesigner的...

  • Xcode调试工具

    一.静态内存分析工具 编译阶段查找内存泄漏等问题 1.常见内存泄漏问题 常见的内存泄漏除了循环引用,CoreFou...

  • 三个方法帮助解决Android内存泄漏问题

    三个方法帮助解决Android内存泄漏问题 最近自己遇到了好几个内存泄漏的问题,也帮同事解决了几个内存泄漏的问题记...

  • 安卓内存泄漏

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...

  • Part1_Android内存泄漏总结

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...

  • Android 内存泄漏总结

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...

  • 【中级——高级迈不过去?】Android高级工程师进阶学习——A

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...

  • Android内存泄漏相关

    问题1 内存泄漏的基本定义是什么?内存泄漏有什么危害?问题2 开发中常见的内存泄漏的情况有哪些?什么原因造成的?怎...

  • 内存泄漏

    内存问题的可能情况 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏...

  • Android_内存泄露

    注意Activity的泄漏 通常来说,Activity的泄漏是内存泄漏里面最严重的问题,它占用的内存多,影响面广,...

网友评论

    本文标题:剖析WorkflowFoundation的内存泄漏问题

    本文链接:https://www.haomeiwen.com/subject/sqhmoctx.html