Mutable(가변객체) immutable(불변객체) 에 대한 질문

안녕하세요 코드몽키님.
우선 예제가 잘 이해가 가지 않는 부분이 있습니다.

1번 테스트는 같은 스택공간의 주소를 넘기셨으니 같은 주소값이 나올 수 밖에 없고,
2번 테스트 역시 0번 인덱스 공간의 주소를 넘기셨으니 같은 주소값이 나올 수 밖에 없습니다. (사실 List list = new List() 문법 때문에 C#으로 테스트하신게 맞는지도 모르겠습니다.)
3번 테스트 역시 string 에서 str += "test"; 코드를 통해 주소값을 바꿔주셨으므로 주소값이 같게 나옵니다. stringbuilder도 첫번째 인덱스만 참조하시니 당연히 같게나옵니다.

명확하게 어떤 것을 테스트하셨는지 잘 모르겠습니다.

우선 .NET에는 Intern Pool이라는 것이있어, 리터럴 문자열에 대한 GC가 관리하지 못하는 특수한 Heap 이 존재합니다.

3번 테스트의 코드를 해석하자면,

string str = "test"; 에서 "test"는 쌍따옴표로 쌓여진 리터럴 문자열이므로, 컴파일 단계에서 Intern Pool로 따로 할당이 됩니다. 따라서 string str의 str에는 Intern Pool의 Heap 주소를 가리키게 됩니다. 이후
str += "test"; 를 하게되면 기존의 “test” 문자열에 대한 변형이 생겨서 "testteset"라는 새로운 문자열이 생성되고 이것은 런타임에서 생성된 문자열이므로 리터럴 문자열이 아니라서 GC Heap의 어딘가에 새로운 문자열이 생성되고, 그 주소값을 str이 저장하게 됩니다. .NET 에서 string이 불변객체라는 것은 이런 뜻입니다.

string을 코드로 변형시키는 시도를 하면, 문자열 자체가 변형되는 것이 아니라 "test"가 있고, "testtest"가 다른 메모리에 새로운 문자열로 할당되는 것입니다. 따라서 기존의 "test"가 변형된게 아니므로 string은 .NET 에서 불변객체입니다.

3번의 stringbuilder는 내부적으로 unsafe와 객체들의 연결리스트 형태로 설계되어있습니다. stringbuilder는 문자열에 변형을 가할 수 있어, 이미 할당된 문자열을 수정할 수 있습니다. unsafe가 이것을 가능하게 합니다. 또한 Append 메서드를 사용할 때 마다, 새로운 string이 할당되고 각각의 string 객체가 따로 놀고있다가 마지막에 ToString() 메서드를 사용할 때 하나로 합쳐줍니다.
따라서 3번 테스트는 …테스트를 잘못하신 것 같습니다.

어떤 테스트를 시도하셨는지 명확하지 않지만, .NET에서의 string 불변은 이해하실 것 같습니다.

6개의 좋아요