.NET 문자열의 가능한 최대 길이는 얼마입니까?


239

.NET에서 만들 수있는 가장 긴 문자열은 무엇입니까? String클래스 의 문서는 내가 볼 수있는 한이 질문에 대해 침묵하므로 권위있는 답변에는 내부 지식이 필요합니다. 64 비트 시스템에서 최대 값이 변경됩니까?

[실제로 사용하는 것보다 호기심이 더 필요합니다. 거대한 문자열을 사용하는 코드를 만들지 않습니다!]

답변:


346

이론적 한계는 2,147,483,647 일 수 있지만 실제 한계는 그 근처에 없습니다. .NET 프로그램의 단일 객체가 2GB를 초과하지 않고 문자열 유형이 UTF-16 (각 문자 당 2 바이트)을 사용하므로 1,073,741,823을 할 수있는 최선의 방법이지만 할당 할 수는 없습니다. 32 비트 시스템에서.

이것은 "당신이 물어봐야한다면 아마도 뭔가 잘못하고있는 것" 중 하나입니다 .


8
이것이 정답입니다. 문자열 길이를 소진하기에 충분히 할당하기 전에 메모리가 부족할 가능성이 큽니다. 새로 부팅 할 때 여기에 언급 된대로 2GB (1M 문자 포함)의 할당량을 가져올 수 있지만 그게 전부입니다.
Stephen Deken

4
"단일 객체가 2Gb를 초과하지 않을 수있다"는 주장이 정확하다고 가정하면, 이것은 이론적 인 한계이자 실제적인 한계입니다. 문자열 길이에 대한 제한은 길이 필드의 용량이 아니라 총 객체 크기가됩니다.
McKenzieG1

12
누군가가 정확한 가치에 관심이 있다면 내 64 비트 시스템에서 1,073,741,791 (1024 · 1024 · 1024-33) 자입니다. 의 정확한 최대 크기에 대한 내 관련 질문byte[] 도 참조하십시오 .
svick

4
짧지 만 심도있는 설명이 포함 된 답변에 열중합니다.
Mikayil Abdullayev

3
64 비트 시스템에서 .NET 4.5 이상 오브젝트를 2GB보다 크게하는 옵션이 있습니다. 여기를 확인하십시오
Anderson Matos

72

고도로 과학적이고 정확한 실험을 바탕으로 1,000,000,000 문자보다 훨씬 앞서 내 컴퓨터에서 완성됩니다. (나는 여전히 더 나은 핀 포인트를 얻기 위해 아래 코드를 실행하고 있습니다).

업데이트 : 몇 시간 후, 나는 포기했습니다. 최종 결과 : System.OutOfMemoryException1,000,000,000 자로 즉시 100,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
}

35
여기서 이진 검색을 적용하면이 답변을 훨씬 빨리 찾을 수 있습니다.
Mario

49

Length속성은 System.String이므로 Int32최대 길이는 2,147,483,647 자 (최대 Int32크기)라고 생각합니다. 그것이 더 길어지면 길이를 확인할 수 없었습니다.


2
@ m.edmondson : 나는 실제로 확신하지 않습니다. 인스턴스 의 배열LongLength 도 마찬가지이며 스트림은 long길이로 사용 됩니다. 올바른 답변이지만 이것을 측정하는 정확한 방법은 없습니다.
Willem Van Onsem

1
그러나이 기사 에서 언급 한 것처럼 첫 두 비트는 ASCII / 비 ASCII 표시 에 사용되므로 2 ^ 30 = 1 073 741 824
Saito

28

이 주제에 대해 늦게 와서 누군가에게, 나는 hitscan의 "아마도 그렇게하지 말아야 할 것"이 누군가가 무엇을해야하는지 물어볼 수 있다는 것을 알 수 있었다.

의 StringBuilder 클래스는 종종 쉽게 교체입니다. 스트림 기반 클래스 중 하나를 고려하십시오.데이터가 파일에서 오는 경우 특히 하십시오.

문제 s += "stuff"는 데이터를 보유하기 위해 완전히 새로운 영역을 할당 한 다음 모든 이전 데이터를 새 데이터와 함께 복사합니다. 각각 및 모든 루프 반복. 따라서 1,000,000에 5 바이트를 추가하면 s += "stuff"비용이 매우 많이 듭니다. 원하는 바를 5 바이트 만 작성하고 프로그램을 계속 진행하려면 성장할 여지를 남겨둔 클래스를 선택해야합니다.

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

StringBuilder것입니다 배로 자동 증가 그것의 한계는 히트 때. 따라서 시작시 한 번, 5,000 바이트에서 한 번, 다시 10,000 번, 다시 20,000 번에서 성장 고통이 나타납니다. 문자열을 추가하면 루프 반복마다 고통이 발생합니다.


4
StringBuilder를 사용하면 초기 크기를 설정할 수 있다는 점도 주목할 가치가 있습니다. 사전에 10,000,000 개의 항목을 사용하고 일부 위기를 무시할 수 있다는 것을 알고있는 경우 유용합니다.
Kyle Baran

3
+1 질문을보고 좋은 디자인에 답변합니다. "실제로 많은 텍스트를 저장해야하는 경우 이것을 사용하십시오 ..."
StevoInco

8

내 컴퓨터 에서 문자열의 최대 길이 는 1,073,741,791 입니다.

알다시피, 문자열은 일반적으로 생각되는 정수에 의해 제한되지 않습니다.

메모리 제한 외에, 문자열은 2 30 ( 1,073,741,824)를 초과 할 수 없습니다 Microsoft CLR (Common Language Runtime)에 의해 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();

}

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

문자열 테스트, Nicholas John Joseph Taylor

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

이것은 문자열의 최대 지원 길이를 찾기 위해 결과를 좁히는 빠른 테스트입니다.

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

s. 옷 길이 = 1000000000 08/05/2019 12:06

'System.OutOfMemoryException'유형의 예외가 발생했습니다. 08/05/2019 12:06에. 데시 메이션 후 증가 값은 100000000입니다.

'System.OutOfMemoryException'유형의 예외가 발생했습니다. 08/05/2019 12:06에. 데시 메이션 후 증분 값은 10000000입니다 .s 08 : 05/2019 12:06에서 s.Length = 1010000000 12/06/2019/08/05에서 12:06 s.Length = 1020000000 12:06 s.Length = 1030000000 at 08/05/2019 12 : 06 s. 길이 = 1040000000 2019 년 8 월 5 일 12:06 s. 길이 = 1050000000 08/05/2019 12:06 s. 길이 = 1060000000 08/05/2019 12:06 s. 길이 = 1070000000 08/05/2019 12:06

'System.OutOfMemoryException'유형의 예외가 발생했습니다. 08/05/2019 12:06에. 데시 메이션 후 증분 값은 1000000입니다 .08 / 05 / 2019 12:06에서 길이 = 1071000000 12:06에서 2019 년 08/05/12에서 길이 = 1072000000 12:06 s. 길이 = 1073000000에서 08/05/2019 12 : 06

'System.OutOfMemoryException'유형의 예외가 발생했습니다. 08/05/2019 12:06에. 데시 메이션 후 증분 값은 100000입니다 .2019 년 8 월 5 일 12:06에서 길이 = 1073100000 12:06 초에서 길이 = 1073200000에서 08/05/2019 12:06에서 길이 = 1073300000 : 06 s. 길이 = 1073400000 08/05/2019 12:06 s. 길이 = 1073500000 08/05/2019 12:06 s. 길이 = 1073600000 08/05/2019 12:06 s. 길이 = 1073700000 08/05/2019 12:06

'System.OutOfMemoryException'유형의 예외가 발생했습니다. 08/05/2019 12:06에. 데시 메이션 후 증가 값은 2019 년 8 월 5 일 12시 06 분에 10000 s. 길이 = 1073710000입니다. 08/05/2019 12:06 초에 길이 = 1073720000입니다. 08/05/2019 12에 길이 = 1073730000 12 : 06 s. 길이 = 1073740000, 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/2019/08 12:06에서 100 = s. Length = 1073741100 12:06 s. Length = 1073741200에서 08/05/2019 12:06 s. Length = 1073741300 at 08/05/2019 12 : 07 s. 길이 = 1073741400 08/05/2019 12:07 s. 길이 = 1073741500 08/05/2019 12:07 s. 길이 = 1073741600 08/05/2019 12:07 s. 길이 = 1073741700 08/05/2019 12:07

'System.OutOfMemoryException'유형의 예외가 발생했습니다. 08/05/2019 12:07에. 데시 메이션 후 증분 값은 10 / s / 2019 12:07에서 10 = s. 길이 = 1073741710 12:07 s. 길이 = 1073741720에서 08/05/2019 12:07 s. 길이 = 1073741730에서 08/05/2019 12 : 07 s. 길이 = 1073741740에서 08/05/2019 12:07 s. 길이 = 1073741750에서 08/05/2019 12:07 s. 길이 = 1073741760에서 08/05/2019 12:07 s. 길이 = 1073741770에서 08/05/2019 12:07 s. 길이 = 1073741780에서 08/05/2019 12:07 s. 길이 = 1073741790에서 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입니다.

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

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


"알다시피, 문자열은 일반적으로 생각되는 정수에 의해 제한되지 않습니다." -> c #의 정수는 최대 2,147,483,647까지 올라갈 수 있으며 결과는이 값에 2로 나눈 값 (32 바이트 더 적음)에 매우 가깝습니다. 이는 문자열의 모든 문자가 2 바이트에 유니 코드로 저장되므로 논리적입니다. 따라서 정수의 크기로 한계가 부과되지 않더라도 그 한계에 매우 가깝습니다.

2

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

5
실제로 하나의 큰 문자열을 만들면 얻을 수있는 동작이 여러 문자열을 할당하고 연결하여보고있는 것과 같은지 확실하지 않습니다.
Casey

2

String.Length의 정수인 정수 이므로 Int32크기는 Int32.MaxValue유니 코드 문자 로 제한됩니다 . ;-)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.