1

WCF クライアントがあり、リクエストを送信する前に保存する必要がありますが、シリアル化のたびに、いくつかのウィンドウ イベント ハンドルがリークされています。Windbg を試しましたが、ハンドルは clr によって作成されます。sysinternals handles.exe を使用すると、セマフォとイベントが常に増加しており、アンマネージ メモリも増加していることがわかります。

Handle type summary:
  ALPC Port       : 10
  Desktop         : 1
  Directory       : 5
  EtwRegistration : 16
  Event           : 574
  File            : 12
  IoCompletion    : 3
  Key             : 13
  KeyedEvent      : 1
  Mutant          : 7
  Process         : 1
  Section         : 11
  Semaphore       : 467
  Thread          : 19
  Timer           : 3
  TpWorkerFactory : 16
  WindowStation   : 2
Total handles: 1161

いくつかのテストの後、この動作は 4.0/4.5 でのみ発生するようです。問題を示すテスト コードを次に示します。

namespace HandleLeak
{
    class Program
    {
        private static XDocument SerializeToSoap(object source)
        {
            TypedMessageConverter messageConverter = TypedMessageConverter.Create(source.GetType(), null, new XmlSerializerFormatAttribute());
            using (Message request = messageConverter.ToMessage(source, MessageVersion.Soap11))
            {
                var xdoc = new XDocument();
                using (var wr = xdoc.CreateWriter())
                {
                    request.WriteMessage(wr);
                }
                return xdoc;
            }
        }

        static void Main(string[] args)
        {
            var sr = new SomeRequest();
            while(true)
            {
                SerializeToSoap(sr);
                GC.Collect();

                var currentProcess = Process.GetCurrentProcess();
                Console.WriteLine("Handles: {0}", currentProcess.HandleCount);
                Console.WriteLine("press any key to continue, esc to quit");
                if (Console.ReadKey(true).Key == ConsoleKey.Escape)
                    break;
            }
            Console.WriteLine("Done");
            Console.ReadKey();
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.1")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://test")]
    public partial class SomeType
    {

    }

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ServiceModel.MessageContractAttribute(IsWrapped = false)]
    public partial class SomeRequest
    {

        [System.ServiceModel.MessageBodyMemberAttribute(Name = "someRequest", Namespace = "http://test", Order = 0)]
        public SomeType statusRequest1;

        public SomeRequest()
        {
        }

        public SomeRequest(SomeType statusRequest1)
        {
            this.statusRequest1 = statusRequest1;
        }
    }
}

問題は、私たちが何か間違ったことをしているのか、それともフレームワークのバグなのかということです。

4

1 に答える 1

3

まあ、私はもう少しグーグルするべきだったことがわかりました:

http://www-jo.se/f.pfleger/memoryleakおよび http://plainoldstan.blogspot.ch/2011/04/wcf-memory-leak-with.html

解決策は、推測したであろうTypedMessageConverterをキャッシュすることです。

于 2012-11-13T14:55:43.727 に答える