문제

.NET에서 생성 할 수있는 가장 긴 문자열은 무엇입니까? The Docs String 수업은 내가 볼 수있는 한이 질문에 대해 침묵하므로 권위있는 답변에는 내부에 대한 지식이 필요할 수 있습니다. 64 비트 시스템의 최대 변화는?

이것은 실제적인 사용보다 호기심을 더 많이 묻습니다 - 나는 거대한 문자열을 사용하는 코드를 만들려는 의도가 아닙니다!

도움이 되었습니까?

해결책

이론적 한계는 2,147,483,647 일 수 있지만 실질적인 한계는 그 근처에 없습니다. .NET 프로그램의 단일 객체는 2GB 이상이고 문자열 유형은 유니 코드 (각 문자마다 2 바이트)를 사용하기 때문에 최선을 다하면 1,073,741,823이지만이를 할당 할 수는 없습니다. 32 비트 기계.

이것은 그 상황 중 하나입니다 "물어봐야한다면 아마도 뭔가 잘못하고있을 것입니다."

다른 팁

과학적이고 정확한 실험을 바탕으로 1,000,000,000 자 전에 내 컴퓨터에서 잘 어울립니다. (더 나은 정확도를 얻기 위해 아래 코드를 여전히 실행하고 있습니다).

업데이트:몇 시간 후, 나는 포기했다. 최종 결과 : 즉시 10 만 명의 문자보다 훨씬 클 수 있습니다. 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" 매우 비용이 많이 듭니다. 당신이 원하는 것이 끝까지 5 바이트를 작성하고 프로그램을 진행한다면, 성장의 여지를 남길 수있는 수업을 선택해야합니다.

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) 문자, 2GB 제한은 Microsoft CLR (공통 언어 런타임)에 의해 부과되므로. 내 컴퓨터가 허용하는 것보다 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();

}

내 결과는 다음과 같습니다.

Nicholas John Joseph Taylor의 현악 테스트

이론적으로 C#은 int.maxvalue의 문자열을 지원해야하지만 그 전에는 메모리가 부족합니다.

이것은 최대 지원되는 스트링 길이를 찾기 위해 결과를 좁히기위한 빠른 테스트입니다.

테스트가 시작됩니다 ... 지금 :

S.length = 10000000000 at 08/05/2019 12:06

'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 1000000000입니다.

'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 100000000입니다. 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 at 08/05/2019 12:06

'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 10000000입니다. 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. 소멸 후 증분 값은 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 at at 08/05/2019 12:06

'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 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

'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 1000입니다. S.length = 1073741000 at 08/05/2019 12:06

'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 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 at 08/05/2019 12:07

'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:07. 소멸 후 증분 값은 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

'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:07. 소멸 후, 증분 값은 1입니다. S.length = 1073741791 at 08/05/2019 12:07

'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:07. 소멸 후, 증분 값은 0입니다. 테스트 완료.

문자열의 최대 길이는 1073741791입니다.

계속하려면 키를 누르십시오.

내 컴퓨터의 문자열의 최대 길이는 1073741791입니다.

사람들이 결과를 아래에 의견으로 게시 할 수 있다면 대단히 감사합니다.

사람들이 동일하거나 다른 결과를 얻는 지 배우는 것이 흥미로울 것입니다.

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

부터 String.Length 정수입니다 (그것은 별명입니다 Int32), 크기는로 제한됩니다 Int32.MaxValue 유니 코드 문자. ;-)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top