문제

우리는 주로 위의 모범 사례를 따르는 경향이 있습니다.

살펴보십시오 문자열 대 StringBuilder

그러나 StringBuilder는 던질 수 있습니다 메모리가 충분한 경우에도 OutofMemoryException. "연속 메모리 블록"이 필요하기 때문에 OOM 예외를 던집니다.

참조를위한 일부 링크StringBuilder OutofMemoryException

그리고 더 많은 것이 있습니다 .....

얼마나 많은 사람들 이이 문제에 직면했거나 알고 있었고, 그것을 해결하기 위해 무엇을 했습니까?

내가 놓친 것이 있습니까?

추신 : 나는 이것을 몰랐다.

나는 질문을 다시 판결했다.

*** 동일한 작업이 수동 연결과 함께 작동했습니다 (이를 확인하고 업데이트 할 것입니다). 나에게 걱정을 일으킨 또 다른 것은 시스템에 충분한 메모리가 있다는 것입니다. 그것이 내가이 질문을 제기하여 어떤 사람 이이 문제에 직면했는지 또는 코드에 크게 잘못되었는지 확인한 이유입니다.

도움이 되었습니까?

해결책

당신이 만든 언론 문자열은 또한 char의 배열로 표시되기 때문에 연속적인 메모리 블록이 필요합니다 (배열은 연속 메모리가 필요합니다). StringBuilder가 OOM 예외를 던지면 Wolud는 그것없이 기본을 구축 할 수 없습니다.

문자열을 작성하면 OOM이 발생하면 응용 프로그램에 더 심각한 문제가있을 수 있습니다.

설명에 대한 응답으로 편집 :

수동 연결이 성공할 때 StringBuilder가있는 문자열을 구축하는 사례의 작은 서브 세트가 있습니다. 수동 연결은 두 줄을 결합하기 위해 필요한 정확한 길이를 사용하는 반면 StringBuilder는 메모리 할당을위한 다른 알고리즘을 갖습니다. 그것은 더 공격적이며 문자열에 실제로 필요한 것보다 더 많은 메모리를 할당 할 것입니다.

StringBuilder를 사용하면 문자열이 시스템에 존재하기 때문에 필요한 메모리가 임시로 두 배가됩니다. STRING 양식 및 StringBuilder는 짧은 시간 동안 동시에 문자열 재산이 있습니다.

그러나 한 가지 방법으로 OOM을 유발하고 다른 방법으로는 그렇지 않다면 여전히 프로그램에서 더 심각한 문제를 가리킬 수 있습니다.

다른 팁

StringBuilder가 특정 상황에서 OutofMemoryException을 던질 경우 수동 문자열 연결을 수행하는 것이 더 나은 솔루션이 아닙니다. 훨씬 더 나쁩니다. 이것은 StringBuilder를 사용해야하는 경우 (매우, 매우 긴 문자열을 만드는 경우) 정확히입니다. 이 큰 문자열의 수동 연결은 StringBuilder가있는 문자열을 만드는 메모리를 여러 번 소요됩니다.

즉, 현대 컴퓨터에서 문자열이 인접한 메모리에서 컴퓨터를 실행합니다 당신의 디자인은 깊고 깊은 결함이 있습니다. 나는 당신이 할 수있는 일이 그 큰 끈을 만들 수있는 일을 상상할 수 없습니다.

우리는 얼마나 많은 기억에 대해 이야기하고 있습니까? 나는 시스템의 무료 또는 총 기억에 대해 이야기하는 것이 아니라, 당신이 연결하는 문자열이 얼마나 걸립니까?

메모리 오버플로 예외는 메모리가 실제로 실행되기 오래 전에 실패하더라도 코드에 대해 거의 나쁜 신호입니다.

이 시점에서 코드를 실제로 재구성해야합니다.

예를 들어, 문제를 해결하는 다양한 방법이 있습니다.

  1. 한 번에 많은 데이터를 메모리에 보관하지 마십시오. 디스크 또는 무언가에 넣으십시오.
  2. 분해하고, 문자열/문자열 빌더 목록을 유지하고 새로 전환하기 전에 특정 길이까지 추가하고 "Continous Memory"문제를 유지하십시오.
  3. 메모리에 기가 바이트를 전혀 구축하지 않도록 알고리즘을 재구성하십시오.

당신이 이것이 당신의 메모리 제한으로 Soclose를 실행하고 있다면, 이것이 걱정이된다면, 아마도 다른 아키텍처에 대해 생각하거나 더 강력한 기계를 얻어야 할 것입니다.

방법을 보면 StringBuilder 구현되면 실제로 사용한다는 것을 알 수 있습니다. String 데이터를 보유하려면 (String 내부 방법이있어 허용됩니다 StringBuilder 제자리에 수정하기 위해).

즉 둘 다 같은 양의 메모리를 사용합니다. 그러나 그 이후로 StringBuilder 메모리 오류의 원인 일 때 필요한 경우 (그러나 용량을 두 배로 늘릴 때) 기본 배열을 자동으로 확장하고 복사합니다. 그러나 다른 사람들이 이미 지속적인 메모리 블록이 필요하다고 지적했듯이

글쎄, 문제는 실제로, 왜 길이 오랫동안 줄로 일해야합니까? 이 문제를 우연히 발견하면 개념을 바꿔야 할 가능성이 높습니다.

이 문제는 심지어 영향을 미칩니다 System.String 클래스, 그래서 당신은 당신의 입력을 목록 <문자열> 데이터를 병렬로 처리하여 올바르게 작성하면 전반적인 성능을 증가시켜야합니다.

나는 다른 StringBuilders (익명 함수 내에서 선언되었으므로 문제를 일으키지 않았을 것임)와 함께 성공적으로 구축 된 매우 큰 문자열 로이 예외를 발견했으며, 마침내 익명 기능 외부에서 선언 한 단일 StringBuilder를 재사용하여 해결했습니다.

나는 줄을 추가하고 있었지만 String.format을 추가하는 것을 잊어 버린 매우 비슷한 경험을 가지고있었습니다. 따라서:

myStringBuilder.Append("1,""{0}""", someVeryLargeIntVariable)

그랬어 야 했어야했다 :

myStringBuilder.Append(String.Format("1,""{0}""", someVeryLargeIntVariable))

이것은 실패한 VB.NET 코드입니다. C#에서 비슷한 테스트를 다시 복제했습니다.

myStringBuilder.Append('a', 1564544656);

vs.

myStringBuilder.Append(string.Format("1,\"{0}\"", 1564544656));

그러나 제 경우에는 vb.net이 암시 적 변환의 곤경에 처하게했습니다 (나는 평행을 이룰 수 없었습니다. 정확한 C#)에서 동일한 문제.

나는 그것이 누군가를 돕기를 바랍니다.

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