Search code examples
wcfgarbage-collectiondatacontractserializer

wcf deserializing without memory allocations


I have a WCF service handling a very large number of requests (thousands per second). Each request contains objects, so they get built inside the DataContractSerializer during deserialization. My service processes the messages, and they get cleaned up by the .net garbage collector.

The problem is that garbage collections are causing problems for my service (requests occasionally taking 100+ milliseconds longer than they should). I need to minimize them. So I am looking for a way of using object pooling. In other words, I want the data contract serializer to obtain an object from my object pool (instead of getting one via GetUninitializedObject), and then when I am done processing the message, I would release it back to the pool for cleaning & reuse, thereby avoiding thousands of memory allocations a second.

I've seen this is possible with protobuf-net (Using protobuf-net, is it possible to deserialize a message without allocating memory?) and in fact I'm using protobuf elsewhere, but for this particular situation that is not an option


Solution

  • The DataContractSerializer is sealed and cannot be updated. So unfortunately you would not be able to remove it's call to FormatterServices.GetUninitializedObject.

    What you will have to do instead is create your own serializer inheriting from XmlObjectSerializer so that you can fully control instance creation.

    The next step is to create a DataContractSerializerOperationBehavior and override the CreateSerializer methods to return your customized serializer.

    Last thing to do is remove the default DataContractSerializerOperationBehavior from the endpoint and replace it with the custom one that implements your custom serializer. Carlos Figueira has a post on his blog showing exactly how to do this (go to the section called Real world scenario: using a new serializer).