调用XmlSerializer.Deserialize()的OutOfMemoryError - 与XML大小无关!

Mik*_*las 8 .net serialization out-of-memory xmlserializer

这是一个非常疯狂的bug.以下是OutOfMemoryException针对非常简短(例如<ABC def='123'/>)的XML snippit 抛出的内容:

public static T DeserializeXmlNode<T>(XmlNode node)
{
    try
    {
        return (T)new XmlSerializer(typeof(T))
            .Deserialize(new XmlNodeReader(node));
    }
    catch (Exception ex)
    {
        throw; // just for catching a breakpoint.
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这篇MSDN文章中读到,如果我在构造函数中使用XmlSerializer和其他参数,我每次调用时都会生成未缓存的序列化程序集,从而导致程序集泄漏.但我没有在构造函数中使用其他参数.它也是在第一次在新启动的AppDomain中调用时发生的,所以这也没有意义.

是什么赋予了?

Mik*_*las 4

好吧,我的问题的最终答案不会帮助每个遇到此问题的人,但我的一些同事几个月后也在不同的系统和不同的产品上遇到了这个问题。几个月后,当他们在这里找到我的帖子时,他们笑了,想知道我是否真的解决了这个问题,因为这里没有接受任何解决方案。

最终的解决方案与反序列化问题无关。相反,它涉及完全卸载并安装 Oracle ODP.NET数据库客户端的全新副本,我们的许多(如果不是全部)应用程序都使用该提供程序。

根据传闻证据,此问题似乎是由未正确修补的 ODP.NET 程序集版本引起的,该程序集随后通过虚拟机克隆传播到其他系统。

当完全删除 ODP.NET,并从 Oracle 网站检索新的兼容版本并安装后,问题完全消失。

假设是可用(但已损坏)的 ODP.NET 驱动程序具有不安全代码,并且Deserialize在首次使用后会重复覆盖该方法附近的 .NET 受保护内存区域。如果在Deserialize任何 ODP.NET 调用之前调用,它会正常工作。但是,使用任何 ODP.NET 调用后对 Deserialize 的所有后续调用都会严重失败。

最终的解决方案现已在两个不同的产品中解决了两次,即安装一个良好/新鲜/干净/新的 ODP.NET 副本。

不太漂亮...但这就是解决问题的方法。