.NET字符串的最大可能长度是多少?

时间:2008-09-26 16:14:35

标签: .net string limits

.NET中可以创建的最长字符串是什么?就我所见,String类的文档对此问题保持沉默,因此权威性答案可能需要一些内部知识。在64位系统上最大的变化是什么?

[这更多是为了好奇而不是实际使用 - 我不打算创建任何使用巨大字符串的代码!]

8 个答案:

答案 0 :(得分:311)

理论上的限制可能是2,147,483,647,但实际限制远非如此。由于.NET程序中没有单个对象可能超过2GB且字符串类型使用Unicode(每个字符2个字节),因此您可以做的最好是1,073,741,823,但是您不可能在32位机器。

这是"If you have to ask, you're probably doing something wrong."

的情况之一

答案 1 :(得分:68)

基于我高度科学和准确的实验,它在我的机器上达到了1,000,000,000个字符之前。 (我仍在运行下面的代码以获得更好的精确定位)。

<强>更新 几个小时后,我放弃了。最终结果:可以超过100,000,000个字符,立即以1,000,000,000个字符给出System.OutOfMemoryException

using System;
using System.Collections.Generic;

public class MyClass
{
    public static void Main()
    {
        int i = 100000000;
        try
        {
            for (i = i; i <= int.MaxValue; i += 5000)
            {
                string value = new string('x', i);
                //WL(i);
            }
        }
        catch (Exception exc)
        {
            WL(i);
            WL(exc);
        }
        WL(i);
        RL();
    }

    #region Helper methods

    private static void WL(object text, params object[] args)
    {
        Console.WriteLine(text.ToString(), args);   
    }

    private static void RL()
    {
        Console.ReadLine(); 
    }

    private static void Break() 
    {
        System.Diagnostics.Debugger.Break();
    }

    #endregion
}

答案 2 :(得分:49)

由于Length的{​​{1}}属性为System.String,我猜测最大长度为2,147,483,647个字符(最大Int32大小)。如果允许的时间更长,则无法检查长度,因为这会失败。

答案 3 :(得分:26)

对于那些迟到这个话题的人来说,我可以看到hitscan的“你可能不应该这样做”可能会让别人问他们应该怎么做......

StringBuilder课程通常很容易替代。 如果您的数据来自文件,请考虑其中一个stream-based classes

s += "stuff"的问题在于它必须分配一个全新的区域来保存数据,然后将所有旧数据复制到它以及新的东西 - 每个循环和每次循环迭代。因此,使用s += "stuff"向1,000,000添加五个字节是非常昂贵的。 如果你想要的只是写五个字节到最后并继续你的程序,你必须选择一个留下一些增长空间的类:

StringBuilder sb = new StringBuilder(5000);
for (; ; )
    {
        sb.Append("stuff");
    }
当受到限制时,<{StringBuilder auto-grow by doubling将会{{3}}。因此,您将在开始时看到增长痛苦,一次是5,000字节,再次是10,000,再次是20,000。追加字符串会在每次循环迭代时产生痛苦。

答案 4 :(得分:7)

我机器上字符串的最大长度为 1,073,741,791

你知道,字符串不受普遍认为的整数限制。

除了内存限制外,字符串不能超过2个 30 1,073,741,824 )个字符,因为Microsoft CLR(公共语言运行时)强加了2GB的限制。比计算机允许的数量多33个。

现在,欢迎您自己尝试一下。

在Visual Studio中创建一个新的C#控制台应用程序,然后在此处复制/粘贴main方法:

static void Main(string[] args)
{
    Console.WriteLine("String test, by Nicholas John Joseph Taylor");

    Console.WriteLine("\nTheoretically, C# should support a string of int.MaxValue, but we run out of memory before then.");

    Console.WriteLine("\nThis is a quickish test to narrow down results to find the max supported length of a string.");

    Console.WriteLine("\nThe test starts ...now:\n");

    int Length = 0;

    string s = "";

    int Increment = 1000000000; // We know that s string with the length of 1000000000 causes an out of memory exception.

    LoopPoint:

    // Make a string appendage the length of the value of Increment

    StringBuilder StringAppendage = new StringBuilder();

    for (int CharacterPosition = 0; CharacterPosition < Increment; CharacterPosition++)
    {
        StringAppendage.Append("0");

    }

    // Repeatedly append string appendage until an out of memory exception is thrown.

    try
    {
        if (Increment > 0)
            while (Length < int.MaxValue)
            {
                Length += Increment;

                s += StringAppendage.ToString(); // Append string appendage the length of the value of Increment

                Console.WriteLine("s.Length = " + s.Length + " at " + DateTime.Now.ToString("dd/MM/yyyy HH:mm"));

            }

    }
    catch (OutOfMemoryException ex) // Note: Any other exception will crash the program.
    {
        Console.WriteLine("\n" + ex.Message + " at " + DateTime.Now.ToString("dd/MM/yyyy HH:mm") + ".");

        Length -= Increment;

        Increment /= 10;

        Console.WriteLine("After decimation, the value of Increment is " + Increment + ".");

    }
    catch (Exception ex2)
    {
        Console.WriteLine("\n" + ex2.Message + " at " + DateTime.Now.ToString("dd/MM/yyyy HH:mm") + ".");

        Console.WriteLine("Press a key to continue...");

        Console.ReadKey();

    }

    if (Increment > 0)
    {
        goto LoopPoint;

    }

    Console.WriteLine("Test complete.");

    Console.WriteLine("\nThe max length of a string is " + s.Length + ".");

    Console.WriteLine("\nPress any key to continue.");

    Console.ReadKey();

}

我的结果如下:

  

字符串测试,作者:Nicholas John Joseph Taylor

     

理论上,C#应该支持一串int.MaxValue,但我们运行   在此之前没有记忆。

     

这是一个快速测试,以缩小结果以找到最大值   支持字符串的长度。

     

测试开始......现在:

     

s.Length = 1000000000 at 08/05/2019 12:06

     

抛出了类型'System.OutOfMemoryException'的异常。在   08/05/2019 12:06经过抽取后,Increment的值为   亿。

     

抛出了类型'System.OutOfMemoryException'的异常。在   08/05/2019 12:06经过抽取后,Increment的值为   10000000. s.Length = 1010000000 at 08/05/2019 12:06 s.Length = 1020000000 at 08/05/2019 12:06 s.Length = 1030000000 at 08/05/2019   12:06 s.Length = 1040000000 at 08/05/2019 12:06 s.Length = 1050000000   于08/05/2019 12:06 s.Length = 1060000000 at 08/05/2019 12:06 s.Length   = 1070000000于08/05/2019 12:06

     

抛出了类型'System.OutOfMemoryException'的异常。在   08/05/2019 12:06抽取后,Increment的值为1000000。   s.Length = 1071000000 at 08/05/2019 12:06 s.Length = 1072000000 at   08/05/2019 12:06 s.Length = 1073000000 at 08/05/2019 12:06

     

抛出了类型'System.OutOfMemoryException'的异常。在   08/05/2019 12:06抽取后,Increment的值为100000。   s.Length = 1073100000 at 08/05/2019 12:06 s.Length = 1073200000 at   08/05/2019 12:06 s.Length = 1073300000 at 08/05/2019 12:06 s.Length =   1073400000于08/05/2019 12:06 s.Length = 1073500000 at 08/05/2019   12:06 s.Length = 1073600000 at 08/05/2019 12:06 s.Length = 1073700000   在08/05/2019 12:06

     

抛出了类型'System.OutOfMemoryException'的异常。在   08/05/2019 12:06抽取后,Increment的值为10000。   s.Length = 1073710000 at 08/05/2019 12:06 s.Length = 1073720000 at   08/05/2019 12:06 s.Length = 1073730000 at 08/05/2019 12:06 s.Length =   1073740000于08/05/2019 12:06

     

抛出了类型'System.OutOfMemoryException'的异常。在   08/05/2019 12:06抽取后,Increment的值为1000。   s.Length = 1073741000 at 08/05/2019 12:06

     

抛出了类型'System.OutOfMemoryException'的异常。在   08/05/2019 12:06抽取后,Increment的值为100。   s.Length = 1073741100于08/05/2019 12:06 s.Length = 1073741200 at at   08/05/2019 12:06 s.Length = 1073741300 at 08/05/2019 12:07 s.Length =   1073741400于08/05/2019 12:07 s.Length = 1073741500 at 08/05/2019   12:07 s.Length = 1073741600 at 08/05/2019 12:07 s.Length = 1073741700   在08/05/2019 12:07

     

抛出了类型'System.OutOfMemoryException'的异常。在   08/05/2019 12:07经过抽取后,Increment的值为10。   s.Length = 1073741710于08/05/2019 12:07 s.Length = 1073741720 at at   08/05/2019 12:07 s.Length = 1073741730 at 08/05/2019 12:07 s.Length =   1073741740于08/05/2019 12:07 s.Length = 1073741750 at 08/05/2019   12:07 s.Length = 1073741760 at 08/05/2019 12:07 s.Length = 1073741770   于08/05/2019 12:07 s.Length = 1073741780于08/05/2019 12:07 s.Length   = 1073741790于08/05/2019 12:07

     

抛出了类型'System.OutOfMemoryException'的异常。在   08/05/2019 12:07抽取后,Increment的值为1。   s.Length = 1073741791于08/05/2019 12:07

     

抛出了类型'System.OutOfMemoryException'的异常。在   08/05/2019 12:07抽取后,Increment的值为0.测试   完整。

     

字符串的最大长度为1073741791。

     

按任意键继续。

我机器上字符串的最大长度为1073741791.

如果人们可以在下面发表评论,我会非常感激。

了解人们是否得到相同或不同的结果会很有趣。

答案 5 :(得分:2)

200 megs ...此时你的应用程序会陷入虚拟暂停,有一个工作集内存,o / s开始表现得像你需要重新启动。

static void Main(string[] args)
{
    string s = "hello world";
    for(;;)
    {
        s = s + s.Substring(0, s.Length/10);
        Console.WriteLine(s.Length);
    }
}

12
13
14
15
16
17
18
...
158905664
174796230
192275853
211503438

答案 6 :(得分:1)

由于String.Length是一个整数(即Int32的别名),因此其大小限制为Int32.MaxValue个unicode字符。 ; - )

答案 7 :(得分:0)

String在您的RAM堆中分配动态内存大小。但是字符串地址存储在堆栈中,该堆栈占用4个字节的内存。