반응형

개발을 하다보면 종종 String을 다루어야 하는 부분에서 누군가는 String을 다른 누군가는 StringBuilder 또는 StringBuffer을 쓰는 것을 볼 수 있다.

 

그냥 지나칠 수 있는 부분중 하나이지만 사실 이 세가지가 무엇이 다른지, 어떻게 사용해야하는지 생각해보고 지나가야 한다.

 

 

String

 

String의 가장 큰 특징불변(immutable)이다.

이와 달리 StringBuffer StringBuilder mutable이다.

 

String 객체는 한번 생성되면 메모리 공간이 변하지 않는 특성이 있다.

따라서 '+'연산 혹은 'concat'을 사용하는 경우 기존 메모리 공간에 추가되는 것이 아닌

새로운 String 객체를 만든 후 해당 메모리를 다시 참조하도록 만드는 방식이다.

 

이 말은 즉슨, String객체는 Heap 메모리 영역에 생성되고, 한번 생성한 객체의 내용은 변경할 수 없으며 해당 String 객체를 참조하지 않게 되는 순간 Garbage collection에 의해 메모리가 할당 해제된다.

 

따라서 String 객체는 잦은 연산이 필요한 경우 매우 나쁜 성능을 보여주게 된다.(잦은 메모리 할당/해제)

하지만, 동기화를 신경쓰지 않고 간단하게 사용하기 위해서는 String이 가장 편리하다.

 

 

 

StringBuffer 그리고 StringBuilder

 

String과 이 두가지 객체의 가장 큰 차이는 기존 메모리를 사용하냐 하지않냐의 차이이다.

String은 연산을 수행할 경우 새로운 메모리를 생성하여 재참조하지만, StringBuffer 그리고 StringBUilder은 새로운 메모리가 아닌 기존 메모리를 이용하여 객체를 관리한다.

 

StringBuffer와 StringBuilder의 차이는 동기화 여부이다.

StringBuffer은 각 메서드마다 Synchronized 키워드가 존재하기에 멀티스테드 환경에서도 동기화를 지원하는 반면 StringBuilder은 동기화를 보장하지 않는다.

 

따라서 단일 스레드라면 StringBuilder을, 멀티 스레드라면 StringBuffer을 사용하는 것이 유리하다.

 

 

따라서 간편하게 이용하고자 할 때는 String

 

동기화를 중요하게 여기는 상황일 때는 StringBuffer

 

동기화 여부와 무관하게 성능을 내고싶을때는 StringBuilder을 이용한다.

 

 

 

 

 

 


JDK 1.5버전 이전에서는 문자열연산(+, concat)을 할때에는 조합된 문자열을 새로운 메모리에 할당하여 참조함으로 인해서 성능상의 이슈가 있었습니다. 그러나 JDK1.5 버전 이후에는 컴파일 단계에서 String 객체를 사용하더라도 StringBuilder로 컴파일 되도록 변경되었습니다. 그리하여 JDK 1.5 이후 버전에서는 String 클래스를 활용해도 StringBuilder와 성능상으로 차이가 없어졌습니다. 하지만 반복 루프를 사용해서 문자열을 더할 때에는 객체를 계속 추가한다는 사실에는 변함이 없습니다. 그러므로 String 클래스를 쓰는 대신, 스레드와 관련이 있으면 StringBuffer를, 스레드 안전 여부와 상관이 없으면 StringBuilder를 사용하는 것을 권장합니다.

 

 

https://12bme.tistory.com/42


 

 

반응형