2010-11-26 2 views
13

C# 컴파일러 또는 .NET CLR은 문자열 리터럴/상수의 현명한 메모리 최적화를 수행합니까? 나는 "문자열 내부화"라는 개념에 대해 들어 봤는데, 프로그램의 두 비트의 코드에서 문자 그대로 "this is a string"은 실제로 동일한 객체를 참조합니다 (아마 안전 할 것입니다. 불변?). 그래도 Google에서 유용한 참고 자료를 찾을 수는 없습니다 ...C#에서는 문자열 리터럴이 컴파일러에서 최적화됩니까?

내가 잘못 들었습니까? 걱정하지 마라. 나는이 정보로 내 코드에서 끔찍한 일을하고있는 것이 아니다. 단지 그것이 어떻게 작동하는지에 대한 나의 이해를 높이고 싶다.

+0

관련 항목 http://stackoverflow.com/q/372547/38206 –

답변

17

편집 : 난 강력 아래의 문이 모든 C# 컴파일러 구현 마찬가지입니다 의심하지만, 내가 ' 실제로 사양에서 보장되는지 모르겠습니다. 사양의 섹션 2.4.4.5는 동일한 문자열 인스턴스를 참조하는 리터럴에 대해 이야기하지만 다른 상수 문자열 표현은 언급하지 않습니다. I 용의자 스펙의 감독입니다. Mads와 Eric에게 이메일을 보내 드리겠습니다.


문자열 리터럴이 아닙니다. 모든 문자열 상수는입니다.그래서 예를 들면, 고려 :

public const string X = "X"; 
public const string Y = "Y"; 
public const string XY = "XY"; 

void Foo() 
{ 
    string z = X + Y; 
} 

컴파일러 (z에 대한) 여기에 연결 두 상수 문자열 사이이기 때문에 결과는 상수 문자열임을 깨닫는다. 따라서 초기 값 z은 동일한 값을 갖는 컴파일 타임 상수이기 때문에 XY 값과 동일한 참조가됩니다.

EDIT : Mads와 Eric의 회신은 Microsoft C# 컴파일러에서 문자열 상수 및 문자열 리터럴 은 보통 같은 방식으로 처리되었지만 다른 구현은 다를 수 있음을 제안했습니다.

+0

다른 어셈블리의 두 개의 동일한 문자열 상수는 동일한 객체를 가리 킵니 까?/지터 인턴 문자열 리터럴이 있습니까? – CodesInChaos

+0

@CodeInChaos : 나는 CompilationRelaxationsAttribute (CompilationRelaxations.NoStringInterning) 속성에 의존한다고 생각한다. 나는 확실히 말하고 싶지 않다. –

+0

안녕하세요 @ 존 키트, 같은 내용으로 항상 인턴 문자열이 동일한 참조를 가지고 있는지 조언을 주시기 바랍니다? 그러한 문자열의 참조를 비교하는 것이 true를 반환한다는 것을 의미합니까? –

6

This article은 문자열 인 에이블 링을 잘 설명합니다. 제품 견적 :

.NET에는 "intern 풀"개념이 있습니다. 기본적으로는 문자열 집합이지만 모든 문자열을 참조 할 때 리터럴 일 경우 문자열을 참조해야합니다. 이 언어는 아마도 언어에 따라 다르지만 C# 및 VB.NET에서는 이 true이고 매우 언어가 보이지 않는 데 놀랐습니다. 일리노이는 매우 쉽게하기 때문에 할 수 있습니다 아마 인턴 리터럴에 실패하는 것보다 쉽습니다.) 뿐만 아니라 리터럴 가 자동으로 구금 된 것으로, 당신은 인턴 문자열을 수동으로 인턴 방법, 그리고 이미 IsInterned 방법을 사용하여 풀에 같은 문자 순서를 가진 구금 문자열이 있는지 확인할 수 있습니다. 다소 다소 은 부울보다 이 아닌 문자열을 직관적으로 반환합니다. 동일한 문자열이 풀에 이면 해당 문자열에 대한 참조가 반환됩니다. 그렇지 않으면 null은 입니다. 마찬가지로, 구금 문자열에 대한 참조를 반환 인턴 방법 - 두 문자열은 수영장 또는 새로 만든 구금 문자열, 또는 풀에 이미이었던 동일한 문자열에 이미있는 경우에 을 통과시켰다.

+1

Sidenote : AppDomain의 라이브 타임 중에 internend 문자열이 해제되지 않으므로 부적절한 intering을 사용하면 메모리 누수가 발생할 수 있습니다. – CodesInChaos

7

예 문자열 리터럴을 최적화합니다. 당신이 볼 수있는 한 가지 간단한 예 :

string s1="A"; 
string s2="A"; 
object.ReferenceEquals(s1,s2); //true 
관련 문제