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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/140468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:06:30  来源:igfitidea点击:

What is the maximum possible length of a .NET string?

.netstringlimits

提问by McKenzieG1

What is the longest string that can be created in .NET? The docs for the Stringclass are silent on this question as far as I can see, so an authoritative answer might require some knowledge of internals. Would the maximum change on a 64-bit system?

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

[This is asked more for curiosity than for practical use - I don't intend to create any code that uses gigantic strings!]

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

回答by HitScan

The theoretical limit may be 2,147,483,647, but the practical limit is nowhere near that. Since no single object in a .NET program may be over 2GB and the string type uses UTF-16 (2 bytes for each character), the best you could do is 1,073,741,823, but you're not likely to ever be able to allocate that on a 32-bit machine.

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

This is one of those situations where "If you have to ask, you're probably doing something wrong."

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

回答by bdukes

Based on my highly scientific and accurate experiment, it tops out on my machine well before 1,000,000,000 characters. (I'm still running the code below to get a better pinpoint).

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

UPDATE:After a few hours, I've given up. Final results: Can go a lot bigger than 100,000,000 characters, instantly given System.OutOfMemoryExceptionat 1,000,000,000 characters.

更新:几个小时后,我放弃了。最终结果:可以超过 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
}

回答by Ryan Farley

Since the Lengthproperty of System.Stringis an Int32, I would guess that that the maximum length would be 2,147,483,647 chars (max Int32size). If it allowed longer you couldn't check the Length since that would fail.

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

回答by user922020

For anyone coming to this topic late, I could see that hitscan's "you probably shouldn't do that" might cause someone to ask what they should do…

对于迟到这个话题的人,我可以看到 hitscan 的“你可能不应该这样做”可能会导致有人问他们应该做什么......

The StringBuilderclass is often an easy replacement. Consider one of the stream-based classesespecially, if your data is coming from a file.

StringBuilder的类往往是一个易于更换。如果您的数据来自文件,请特别考虑基于流的类之一。

The problem with s += "stuff"is that it has to allocate a completely new area to hold the data and then copy all of the old data to it plus the new stuff - EACH AND EVERY LOOP ITERATION. So, adding five bytes to 1,000,000 with s += "stuff"is extremely costly. If what you want is to just write five bytes to the end and proceed with your program, you have to pick a class that leaves some room for growth:

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

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

StringBuilderwill auto-grow by doublingwhen it's limit is hit. So, you will see the growth pain once at start, once at 5,000 bytes, again at 10,000, again at 20,000. Appending strings will incur the pain every loop iteration.

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

回答by WonderWorker

The max length of a string on my machineis 1,073,741,791.

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

You see, Strings aren't limited by integer as is commonly believed.

你看,字符串并不像人们普遍认为的那样受整数限制。

Memory restrictions aside, Strings cannot have more than 230(1,073,741,824) characters, since a 2GB limit is imposed by the Microsoft CLR (Common Language Runtime). 33 more than my computer allowed.

除了内存限制,字符串不能超过 2 30( 1,073,741,824) 个字符,因为 Microsoft CLR(公共语言运行时)规定了 2GB 的限制。比我的电脑允许的多 33。

Now, here's something you're welcome to try yourself.

现在,这里有一些东西欢迎你自己尝试。

Create a new C# console app in Visual Studio and then copy/paste the main method here:

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

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();

}

My results were as follows:

我的结果如下:

String test, by Nicholas John Joseph Taylor

Theoretically, C# should support a string of int.MaxValue, but we run out of memory before then.

This is a quickish test to narrow down results to find the max supported length of a string.

The test starts ...now:

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

Exception of type 'System.OutOfMemoryException' was thrown. at 08/05/2019 12:06. After decimation, the value of Increment is 100000000.

Exception of type 'System.OutOfMemoryException' was thrown. at 08/05/2019 12:06. After decimation, the value of Increment is 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 at 08/05/2019 12:06 s.Length = 1060000000 at 08/05/2019 12:06 s.Length = 1070000000 at 08/05/2019 12:06

Exception of type 'System.OutOfMemoryException' was thrown. at 08/05/2019 12:06. After decimation, the value of Increment is 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

Exception of type 'System.OutOfMemoryException' was thrown. at 08/05/2019 12:06. After decimation, the value of Increment is 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 at 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 at 08/05/2019 12:06

Exception of type 'System.OutOfMemoryException' was thrown. at 08/05/2019 12:06. After decimation, the value of Increment is 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 at 08/05/2019 12:06

Exception of type 'System.OutOfMemoryException' was thrown. at 08/05/2019 12:06. After decimation, the value of Increment is 1000. s.Length = 1073741000 at 08/05/2019 12:06

Exception of type 'System.OutOfMemoryException' was thrown. at 08/05/2019 12:06. After decimation, the value of Increment is 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 s.Length = 1073741400 at 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 at 08/05/2019 12:07

Exception of type 'System.OutOfMemoryException' was thrown. at 08/05/2019 12:07. After decimation, the value of Increment is 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 s.Length = 1073741740 at 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 at 08/05/2019 12:07 s.Length = 1073741780 at 08/05/2019 12:07 s.Length = 1073741790 at 08/05/2019 12:07

Exception of type 'System.OutOfMemoryException' was thrown. at 08/05/2019 12:07. After decimation, the value of Increment is 1. s.Length = 1073741791 at 08/05/2019 12:07

Exception of type 'System.OutOfMemoryException' was thrown. at 08/05/2019 12:07. After decimation, the value of Increment is 0. Test complete.

The max length of a string is 1073741791.

Press any key to continue.

字符串测试,由 Nicholas John Joseph Taylor

理论上,C#应该支持int.MaxValue的字符串,但是在那之前我们内存不足。

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

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

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

抛出了“System.OutOfMemoryException”类型的异常。在 08/05/2019 12:06。抽取后,Increment 的值为 100000000。

抛出了“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 = 109 at 08/05/2019 :06 s.Length = 1040000000 at 08/05/2019 12:06 s.Length = 1050000000 at 08/05/2019 12:06 s.Length = 1060000000 at 08/05/2010:08/05/10:10 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 = 008/08/05/1009 :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 = 100700008/05/2019 :06 s.Length = 1073400000 at 08/05/2019 12:06 s.Length = 1073500000 at 08/05/2019 12:06 s.Length = 1073600000 at 08/05/2019:1073600000 at 08/05/103:7 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 = 1080703773/2019 :06 s.Length = 1073740000 at 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 at 08/05/2019 12:06 s.Length = 1073741200 at 08/05/2019 12:06 s.Length = 307051200/107051204 :07 s.Length = 1073741400 at 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 = 1073741600 at 08/0701023:4 08/05/2019 12:07

抛出了“System.OutOfMemoryException”类型的异常。在 08/05/2019 12:07。抽取后,Increment 的值为 10。 s.Length = 1073741710 at 08/05/2019 12:07 s.Length = 1073741720 at 08/05/2019 12:07 s.Length = 10705/120180 :07 s.Length = 1073741740 at 08/05/2019 12:07 s.Length = 1073741750 at 08/05/2019 12:07 s.Length = 1073741760 at 08/07/1703:4:73 08/05/2019 12:07 s.Length = 1073741780 at 08/05/2019 12:07 s.Length = 1073741790 at 08/05/2019 12:07

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

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

字符串的最大长度为 1073741791。

按任意键继续。

The max length of a string on my machine is 1073741791.

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

I'd appreciate it very much if people could post their results as a comment below.

如果人们可以在下面发表评论,我将不胜感激。

It will be interesting to learn if people get the same or different results.

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

回答by loudej

200 megs... at which point your app grinds to a virtual halt, has about a gig working set memory, and the o/s starts to act like you'll need to reboot.

200 megs ...此时您的应用程序会陷入虚拟停止状态,大约有一个演出工作集内存,并且操作系统开始表现得好像您需要重新启动一样。

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

回答by VVS

Since String.Lengthis an integer (that is an alias for Int32), its size is limited to Int32.MaxValueunicode characters. ;-)

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