美文网首页生活、程序、健身程序员
剖析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的内存泄漏问题

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