260

.NET 中可以创建的最长字符串是多少?据我所知,该课程的文档String对这个问题保持沉默,因此权威答案可能需要一些内部知识。64 位系统上的最大值会发生变化吗?

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

4

8 回答 8

376

理论极限可能是 2,147,483,647,但实际极限远不及此。由于 .NET 程序中没有单个对象可能超过 2GB,并且字符串类型使用 UTF-16(每个字符 2 个字节),因此您可以做的最好的事情是 1,073,741,823,但您不太可能能够分配它在 32 位机器上。

这是“如果你不得不问,你可能做错了什么”的情况之一。

于 2008-09-26T17:18:23.433 回答
73

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

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

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
}
于 2008-09-26T17:06:29.373 回答
52

由于 的Length属性System.StringInt32,我猜最大长度为 2,147,483,647 个字符(最大Int32大小)。如果它允许更长的时间,您将无法检查长度,因为那会失败。

于 2008-09-26T16:17:54.187 回答
31

对于迟到的人来说,我可以看到即时扫描的“你可能不应该这样做”可能会导致有人问他们应该做什么......</p>

StringBuilder类通常很容易替换。如果您的数据来自文件,请特别考虑其中一个基于流的类。

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

StringBuilder sb = new StringBuilder(5000);
for (; ; )
    {
        sb.Append("stuff");
    }

StringBuilder达到上限时会自动加倍增长。因此,您将在开始时看到一次增长的痛苦,一次是 5,000 字节,再次是 10,000 字节,再次是 20,000 字节。附加字符串会在每次循环迭代时产生痛苦。

于 2014-08-11T15:58:08.437 回答
11

我机器上字符串的最大长度是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 在 08/05/2019 12:06

引发了“System.OutOfMemoryException”类型的异常。在 2019 年 8 月 5 日 12:06。抽取后,Increment 的值为 100000000。

引发了“System.OutOfMemoryException”类型的异常。在 2019 年 8 月 5 日 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 秒长度 = 1040000000 在 08/05/2019 12:06 秒长度 = 1050000000 在 08/05/2019 12:06 秒长度 = 1060000000 在 08/05/2019 12:06 秒长度 = 1070000000 在2019 年 8 月 5 日 12:06

引发了“System.OutOfMemoryException”类型的异常。在 2019 年 8 月 5 日 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”类型的异常。在 2019 年 8 月 5 日 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 秒长度 = 1073400000 在 08/05/2019 12:06 秒长度 = 1073500000 在 08/05/2019 12:06 秒长度 = 1073600000 在 08/05/2019 12:06 秒长度 = 1073700000 在2019 年 8 月 5 日 12:06

引发了“System.OutOfMemoryException”类型的异常。在 2019 年 8 月 5 日 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”类型的异常。在 2019 年 8 月 5 日 12:06。抽取后,Increment 的值为 1000。s.Length = 1073741000 at 08/05/2019 12:06

引发了“System.OutOfMemoryException”类型的异常。在 2019 年 8 月 5 日 12:06。抽取后,Increment 的值为 100。 s.Length = 1073741100 at 08/05/2019 12:06 s.Length = 1073741200 at 08/05/2019 12:06 s.Length = 1073741300 at 08/05/2019 12 :07 秒长度 = 1073741400 在 08/05/2019 12:07 秒长度 = 1073741500 在 08/05/2019 12:07 秒长度 = 1073741600 在 08/05/2019 12:07 秒长度 = 1073741700 在2019 年 8 月 5 日 12:07

引发了“System.OutOfMemoryException”类型的异常。在 2019 年 8 月 5 日 12:07。抽取后,Increment 的值为 10。 s.Length = 1073741710 at 08/05/2019 12:07 s.Length = 1073741720 at 08/05/2019 12:07 s.Length = 1073741730 at 08/05/2019 12 :07 秒长度 = 1073741740 在 08/05/2019 12:07 秒长度 = 1073741750 在 08/05/2019 12:07 秒长度 = 1073741760 在 08/05/2019 12:07 秒长度 = 1073741770 在2019 年 8 月 5 日 12:07 秒长度 = 1073741780 2019 年 8 月 5 日 12:07 秒长度 = 1073741790 2019 年 8 月 5 日 12:07

引发了“System.OutOfMemoryException”类型的异常。在 2019 年 8 月 5 日 12:07。抽取后,Increment 的值为 1。 s.Length = 1073741791 在 08/05/2019 12:07

引发了“System.OutOfMemoryException”类型的异常。在 2019 年 8 月 5 日 12:07。抽取后,Increment 的值为 0。测试完成。

字符串的最大长度为 1073741791。

按任意键继续。

我机器上字符串的最大长度是 1073741791。

如果人们可以将他们的结果作为评论发布在下面,我将非常感激。

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

于 2015-08-04T07:46:01.277 回答
2

由于String.Length是一个整数(即 的别名Int32),它的大小仅限于Int32.MaxValueunicode 字符。;-)

于 2008-09-26T16:20:14.087 回答
1

200 兆...此时您的应用程序几乎停止运行,大约有一个 gig 工作集内存,并且操作系统开始表现得好像您需要重新启动一样。

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
于 2008-09-26T18:06:09.213 回答
0

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

于 2020-10-13T07:26:27.753 回答