Answers:
理论极限可能是2,147,483,647,但实际极限还远远没有达到这个极限。由于.NET程序中的任何单个对象都不能超过2GB,并且字符串类型使用UTF-16(每个字符2个字节),因此您最好能做到1,073,741,823,但是您不可能分配在32位计算机上。
byte[]
。
根据我高度科学和准确的实验,它在我的机器上达到了1,000,000,000个字符。(我仍在运行下面的代码以获得更好的定位)。
更新:
几个小时后,我放弃了。最终结果:可以超过100,000,000个字符,立即给出System.OutOfMemoryException
1,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
}
由于的Length
属性System.String
是Int32
,我猜最大长度为2,147,483,647个字符(最大Int32
大小)。如果允许更长的时间,您将无法检查“长度”,因为那样会失败。
对于迟到这个话题的任何人,我都能看到hitscan的“您可能不应该这样做”可能会引起某人问他们应该怎么做……
该StringBuilder的类往往是一个易于更换。如果您的数据来自文件,则请考虑一种基于流的类。
问题s += "stuff"
在于它必须分配一个全新的区域来保存数据,然后将所有旧数据复制到其中,再加上新的内容-每个循环。因此,将5个字节加到1,000,000 s += "stuff"
将非常昂贵。如果只想在末尾写入五个字节并继续执行程序,则必须选择一个有一定增长空间的类:
StringBuilder sb = new StringBuilder(5000);
for (; ; )
{
sb.Append("stuff");
}
StringBuilder
当达到极限时,将通过加倍自动增长。因此,您一开始就会看到增长的痛苦,一次是5,000字节,一次是10,000,再一次是20,000。追加字符串将在每次循环迭代时带来痛苦。
我的机器上字符串的最大长度为1,073,741,791。
您会发现,字符串并不像通常认为的那样受整数限制。
除了内存限制,字符串不能超过2 30(1,073,741,824)个字符,因为Microsoft CLR(公共语言运行时)施加了2GB的限制。比我的电脑允许的数量多33个。
现在,欢迎您尝试一下。
在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();
}
我的结果如下:
字符串测试,作者:尼古拉斯·约翰·约瑟夫·泰勒
从理论上讲,C#应该支持int.MaxValue字符串,但是在此之前我们用光了内存。
这是一项快速测试,可以缩小结果范围以找到字符串的最大支持长度。
测试开始...现在:
长度= 1000000000在08/05/2019 12:06
引发了类型为'System.OutOfMemoryException'的异常。在08/05/2019 12:06。抽取后,增量的值为100000000。
引发了类型为'System.OutOfMemoryException'的异常。在08/05/2019 12:06。抽取后,增量的值为10000000.s长度= 1010000000(在08/05/2019 12:06 s.Length = 1020000000在08/05/2019 12:06 s.Length = 1030000000在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/08/2019 12:06
引发了类型为'System.OutOfMemoryException'的异常。在08/05/2019 12:06。抽取后,增量的值为1000000.s的长度= 1071000000在08/05/2019 12:06 s.Length = 1072000000在08/05/2019 12:06 s.Length = 1073000000在08/05/2019 12 :06
引发了类型为'System.OutOfMemoryException'的异常。在08/05/2019 12:06。抽取后,增量值为100000.s.Length = 1073100000在08/05/2019 12:06 s.Length = 1073200000在08/05/2019 12:06 s.Length = 1073300000在08/05/2019 12 :06 s.Length = 1073400000在08/05/2019 12:06 s.Length = 1073500000在08/05/2019 12:06 s.Length = 1073600000在08/05/2019 12:06 s.Length = 1073700000在08/08/2019 12:06
引发了类型为'System.OutOfMemoryException'的异常。在08/05/2019 12:06。抽取后,增量的值为10000.s.Length = 1073710000在08/05/2019 12:06 s.Length = 1073720000在08/05/2019 12:06 s.Length = 1073730000在08/05/2019 12 :06 s.Length = 1073740000 at 08/05/2019 12:06
引发了类型为'System.OutOfMemoryException'的异常。在08/05/2019 12:06。抽取后,Increment的值为1000。s.Length = 1073741000在08/05/2019 12:06
引发了类型为'System.OutOfMemoryException'的异常。在08/05/2019 12:06。抽取后,增量的值为100.s.Length = 1073741100在08/05/2019 12:06 s.Length = 1073741200在08/05/2019 12:06 s.Length = 1073741300在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
引发了类型为'System.OutOfMemoryException'的异常。在08/05/2019 12:07。抽取后,增量的值为10.s.Length = 1073741710在08/05/2019 12:07 s.Length = 1073741720在08/05/2019 12:07 s.Length = 1073741730在08/05/2019 12 :08 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在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。抽取后,“增量”的值为0。测试完成。
字符串的最大长度是1073741791。
按任意键继续。
我的机器上字符串的最大长度为1073741791。
如果人们可以将其结果发表在下面的评论中,我将非常感激。
了解人们获得相同或不同结果的过程将很有趣。
200兆...在这时,您的应用程序会陷入虚拟停顿,大约有演出工作集内存,并且操作系统开始表现为您需要重新启动。
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