【问题标题】:"new string" throws out of memory exception“新字符串”抛出内存异常
【发布时间】:2013-12-10 16:30:51
【问题描述】:

谁能帮忙? 在使用 xml 序列化时,我遇到内存不足异常,同时尝试分配巨大的内存块,例如使用“新字符串()”

这是我的测试程序,显示分配问题:

using System;
using System.Text;
namespace Out_of_memory_Exception
{

class Program
{
    static Encoding MyEncoding = Encoding.Default;
    static string Position = "";

    static void Main(string[] args)
    {
        System.Console.WriteLine("Out of memory Exception-Test:");

        const int MEGABYTE = 1024*1024;
        for(long i=10*MEGABYTE; ; i+=10*MEGABYTE)
        {
            try
            {
                System.Console.Write("{0} MB: ", i/(1024*1024));
                Test(i);
                System.Console.WriteLine("OK");
            }
            catch (Exception ex)
            {
                System.Console.WriteLine("{0} at {1}", ex.GetType().ToString(), Position);
            }
            if (i > (1000*MEGABYTE))
                i = 10*MEGABYTE;
        }
    }

    static void Test(long i)
    {
        Position = "new byte[i]";
        byte[] Bytes = new byte[i];

        Position = "Encoding.GetChars()";
        char[] Chars = MyEncoding.GetChars(Bytes);

        Position = "new string()";
        string s = new string(Chars);
    }
}
}

在我的机器上,从 10 到 140 兆字节都可以,超过这个限制我的“新字符串”会引发内存不足异常。

为什么?

【问题讨论】:

  • 你不能序列化到文件流而不是内存流吗?这样,您仅受分配的磁盘配额的限制。只需保留文件引用,直到您可以处理它。
  • 你应该看看你是否可以序列化成更小的部分,例如通过使用Stream,您不必一次将整个内容加载到内存中。
  • 我真的很惊讶这个问题在没有说明任何理由的情况下被否决,这是一个非常真实和真实的问题,任何试图编写自己的序列化代码的人都会遇到这个问题,至少他们将不得不考虑这种情况

标签: c# memory-management out-of-memory


【解决方案1】:

您正在耗尽内存。也许你没有分配所有可用内存,但是进程虚拟地址空间已经被这个程序碎片化了。最终分配器无法找到连续的内存块来满足您的分配请求。

您的解决方案将是以下之一:

  1. 分配更少的内存,即减少需求。
  2. 切换到 64 位进程和更大的盒子,即增加供应。
  3. 以更小的块分配内存,即减少碎片。

另请注意,您的测试分配的字符串占用的空间是您想象的两倍。您的字节数组被视为 ANSI 并转换为 UTF-16。这从 8 位元素扩大到 16 位元素。

【讨论】:

  • 不过有点奇怪。您应该能够使用 CLR 分配巨大的内存块。我尝试使用 GC 类告诉垃圾收集器转储所有未使用的块,但根本没有成功。
  • 您的访问模式导致了虚拟地址空间的碎片化。为了分配大块,必须有可用的内存和连续的地址空间。你已经在地址空间上打了个洞。
  • 请注意,您的字符串比您想象的要大一倍。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-26
  • 1970-01-01
  • 2016-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多