Skip to content

Latest commit

 

History

History
87 lines (53 loc) · 6.37 KB

String,StringBuilder, StringBuffer차이.md

File metadata and controls

87 lines (53 loc) · 6.37 KB

String, StringBuilder, StringBuffer의 차이점과 장단점

String, StringBuilder, StringBuffer는 문자열 클래스들이다. 모두 문자열을 저장하고 관리하는 클래스인데 무엇이 다를까?

면접 시 자주 나오는 질문 중에 하나이기 때문에 정리를 해보았다.

String

String은 문자열을 대표하는 것으로 문자열을 조작하는 경우 유용하게 사용할 수 있다.

먼저 String과 다른 클래스(StringBuffer, StringBuilder)의 차이점은 String은 immutable(불변), StringBuffer, StringBuildermutable(변함)에 있다.

String 객체는 한번 생성되면 할당된 메모리 영역이 변하지 않는다.

+연산자 또는 concat 메소드를 통해 기존에 생성된 String 객체 문자열에 다른 문자열을 붙인다고 하자,

기존 문자열에 새로운 문자열을 붙이는 것이 아니라 새로운 String 객체를 만든 후, 새 String 객체에 연결된 문자열을 저장하고 그 객체를 참조하도록 한다.

즉, String 클래스 객체는 Heap 메모리 영역(가비지 컬렉션이 동작하는 영역)에 생성하고 한번 생성된 객체의 내부 내용을 변화시킬 수 없다.

이렇게 새로운 문자열이 만들어지면 '기존의 문자열'은 가비지 컬렉터에 의해 제거돼야 하는 단점이 있다.

heap 메모리 영역이란 프로그램이 운영체제로부터 할당받는 메모리 공간 중 하나로, 메모리 공간이 동적으로 할당되고 해제된다.

Garbage Collection란 Heap 영역의 메모리를 JVM이 판단해 더 이상 사용되지 않는 인스턴스는 자동으로 할당된 메모리를 삭제하는 역할을 하는 행위이다.

이해를 돕도록 아래의 예시를 보자.

String 객체

String 객체 특성

String 주소값

출처 ifuwanna.tistory

위에 예제에서 "hello"값을 가지고 있던 String 클래스의 참조 변수 str이 가리키는 곳에 "world"문자열을 더해 "hello world"로 변경한 것으로 착각할 수 있다.

하지만 "hello"값이 들어가 있던 String 클래스의 참조 변수 str이 "hello world"라는 값을 가지고 있는 새로운 메모리 영역을 가리키게 변경되고 기존에 "hello"로 값이 할당되어 있던 메모리 영역은 가비지 컬렉션에 의해 사라지게 된다.

이클립스를 사용해 주소값을 출력해보니 가리키는 메모리 영역이 다른 것을 확인할 수 있다.

따라서 String 객체는 이러한 이유로 문자열 연산이 많은 경우, 계속해서 문자열 객체를 만들기 때문에 오버헤드가 발생해 그 성능이 좋지 않다.

하지만 String 객체와 같이 Immutable한 객체는 간단하게 사용 가능하고 불변하기 때문에 동기화에 대해 신경 쓰지 않아도 되기 때문에 멀티 스레드 환경에서 사용가능하다.

String 클래스가 적절한 경우

결론적으로 String 클래스는 문자열 연산이 적고, 자주 참조하는 경우에 사용하면 좋다.

StringBuffer와 StringBuilder

그러면 StringBufferStringBuilder 클래스를 한번 보도록 하자

StringBuffer/StringBuilderString과 다르게 동작한다.

String 과는 반대로 StringBuffer/StringBuilder는 가변성을 가지기 때문에 .apppend() .delete() 등의 API를 이용하여 동일 객체 내에서 문자열을 변경하는 것이 가능하다.

StringBuffer, StringBuilder

StringBuffer 주소

출처 ifuwanna.tistory

위에 StringBuffer 클래스가 참조하는 sb 객체에 "hello"를 저장하고, 이 객체에 .append()를 이용해 "world"를 더하면 sb 객체가 가리키는 메모리 영역은 변하지 않는다. StringBuilder 클래스를 사용하는 경우에도 값은 동일했다.

문자열 연산을 할 때, 클래스는 한 번만 만들고 메모리의 값을 변경시켜서 문자열을 변경한다. 문자열 연산(추가, 수정, 삭제)이 자주 있을 때 사용하면 성능이 좋다는 장점이 있다.

그렇다면 두 클래스의 차이점은 무엇일까? 바로 동기화 여부이다.

StringBuffer는 각 메소드 별로 Synchronized Keyword가 존재하여, 멀티 스레드 환경에서도 동기화를 지원한다.

여러 스레드로부터 동시에 접근이 일어나도 프로그램의 실행에 문제가 없는 것을 thread-safe라고 한다.

반면, StringBuilder는 동기화를 보장하지 않기 때문에 thread-safe 하지 않다.

이러한 특성 때문에 멀티 스레드 환경이라면 값 동기화 보장을 위해 StringBuffer를 사용하고, 단일 스레드 환경이라면 StringBuilder를 사용하는 것이 좋다. StringBuilder가 동기화를 고려하지 않기 때문에 단일 스레드 환경에서 StringBuffer에 비해 연산처리가 빠른 장점이 있다.

StringBuffer, StringBuilder가 적절한 경우

결론적으로 문자열 연산이 많을 때 두 클래스를 사용하지만 멀티 스레드 환경에서는 StringBuffer를 사용하면 좋고, 단일 스레드 환경이거나 멀티 스레드여도 굳이 동기화가 필요 없는 경우에는 StringBuilder를 사용하는 것이 좋다.

정리

  • String : 문자열 연산이 적고 멀티 쓰레드 환경일 경우
  • StringBuffer : 문자열 연산이 많고 멀티 쓰레드 환경일 경우
  • StringBuilder : 문자열 연산이 많고 단일 쓰레드이거나 동기화를 고려하지 않아도 되는 멀티 쓰레드일 경우

Reference