如何克服.net中的内存不足异常

时间:2016-10-03 18:32:16

标签: c# .net xml linq out-of-memory

我有大小为6 GB的大型XML文件,但我只想从XML文件的几个部分获得一个小片段。我使用(XElement)XNode.ReadFrom()方法并且工作得很好。但现在必要的片段也像任何东西一样生长并投掷内存不足异常。如何解决这个问题

using (XmlReader xr = XmlReader.Create(path))
{
    xr.MoveToContent();
    XNamespace un = xr.LookupNamespace("un");
    while (xr.Read())
    {
        while (xr.NodeType == XmlNodeType.Element && xr.NamespaceURI == un && xr.LocalName == "M_ROOT")
        {
            XElement pin = (XElement)XNode.ReadFrom(xr);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

  

为什么你认为当你只需要一个大型XML文件(6 GB大小)的小片段时,它是否导致Out of Memory Exception (OOM),因为你明白这一点:

  1. 32位系统与64位系统的虚拟内存限制
  2. 您是否对内存进行了分析(使用Perfmon,UMDH)以了解模式
  3.   

    让我解释几个重要方面:

    1. 32位系统可以将进程的最大虚拟内存设置为4GB = 2^32 bytes,这是由处理器设计的,但不是整个4 GB可供用户进程使用,默认情况下在Windows上它是user process为2 GB,Kernel process为2 GB,这就是为什么大多数32位进程在接近2 GB时抛出OOM的原因。这不是完全RAM分配,而是虚拟内存,其中包括磁盘上的分页内存。
    2.   

      64位的值是多少?

      1. 理论上简单,2 ^ 64~16艾字节,但这不是大多数操作系统可以映射或硬件可以支持的限制,但对于您正在进行的操作类型仍然是一个巨大的价值,即使它超过32位,但很容易在64位范围内,用户和内核进程内存之间也有清晰的分离
      2.   

        可以提取32位存储器以获得更高的存储空间

        1. 是的,BIOS中有某些标志,如/ 3GB,这可以将用户进程分配增加到3 GB,但这是最大的,因为它将内核进程压缩到1 GB限制,它冒着重度内核操作失败的风险因此通常不建议调整BIOS设置
        2.   

          为什么你的进程在32位和64位编译?

          1. 系统是64位,它能够使用WOW64(Windows on Windows)技术运行甚至32位二进制文​​件,其他方式是不可能的
          2.   

            如何分析

            1. 简单使用Perfmon(最适合这种初始分析)和给定的进程监视器虚拟字节和专用字节,你会看到内存图的线性增加,没有因GC而没有解除分配,因为你没有在上面的代码和最终一致的OOM大约2GB,它将以字节为单位显示值,除以1024 * 1024以获取GB值
            2.   

              您当前的计划有什么问题?

              1. 你提到了6 GB文件,我看到你读到最后,所以这意味着所有内容都会被加载到内存中并进行32位进程,因为它达到2 GB会导致OOM