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

后端 未结 8 1669
梦毁少年i
梦毁少年i 2020-11-22 02:48

What is the longest string that can be created in .NET? The docs for the String class are silent on this question as far as I can see, so an authoritative answe

相关标签:
8条回答
  • 2020-11-22 03:20

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

    0 讨论(0)
  • 2020-11-22 03:25

    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.

    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
    
    0 讨论(0)
  • 2020-11-22 03:26

    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…

    The StringBuilder class is often an easy replacement. Consider one of the stream-based classes especially, if your data is coming from a file.

    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:

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

    StringBuilder will auto-grow by doubling when 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.

    0 讨论(0)
  • 2020-11-22 03:27

    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.

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

    0 讨论(0)
  • 2020-11-22 03:28

    The max length of a string on my machine is 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.

    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:

    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.

    The max length of a string on my machine is 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.

    0 讨论(0)
  • 2020-11-22 03:29

    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).

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

    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
    }
    
    0 讨论(0)
提交回复
热议问题