wadewegner / Force.com-Toolkit-for-NET

The Force.com Toolkits for .NET provides an easy way for .NET developers to interact with the Force.com & Chatter REST APIs using native libraries.
BSD 3-Clause "New" or "Revised" License
374 stars 396 forks source link

XmlSerializer Memory Leak - Created Inside Loop #329

Open ghost opened 5 years ago

ghost commented 5 years ago

The class SObjectList function WriteXml(XmlWriter writer) creates a new XmlSerlializer inside a loop, which is very inefficient. Putting the serializer creation outside of the loop increases speed and decreases memory usage.

Each new XmlSerlializer is internally compiled and cached, so for long running applications* the memory usage will slowly rise over time as the cached serializers can never be garbage collected. To reuse a cached serializer you must use a constructor XmlSerializer(typeof(T)) but that means you will need to use an [XmlRoot("sObject")] attribute on your models (?). Or use your own caching strategy, see this link for details:

https://stackoverflow.com/questions/23897145/memory-leak-using-streamreader-and-xmlserializer

* We use Azure Functions to send bulk data to Salesforce on a schedule, which would slowly climb to >3GB private bytes used before crashing. Since making this change the private bytes used have flat-lined at ~200MB

EricHirst-BZ commented 5 years ago

It looks like https://github.com/developerforce/Force.com-Toolkit-for-NET/pull/255 would fix this. You're right; the code in SObject will definitely result in a memory leak.