관리 메뉴

공부한것들을 정리하는 블로그 입니다.

String, StringBuffer, StringBuilder 차이점 본문

JAVA/공부

String, StringBuffer, StringBuilder 차이점

호 두 2022. 5. 18. 15:06
반응형

오랜만에 String, StringBuffer, StringBuilder 차이점에 대해 리마인드 해봅니다.

 

String, StringBuffer, StringBuilder 차이점

# String

- 가장 큰 차이는 String은 불변성을 가진다는 점입니다.
- 가령 "hello" 값을 가지고 있던 String 클래스의 참조변수에 "World" 문자열을 더하게 될 경우 단순히 문자열이 "helloWorld"로 수정된 것이 아니라,
- 기존에 "hello" 값이 들어가 있던 String 클래스의 참조변수가 "helloWorld"라는 값을 가지고 있는 새로운 메모리 영역을 가리키도록 변경되고, 처음 선언했던 "hello"로 값이 할당되어 있던 메모리 영역은 GC에 의해 제거 대상이 됩니다.
- 이처럼 String 클래스는 불변하기 때문에 문자열을 수정하는 시점에 새로운 String 인스턴스가 생성되기 때문에, 문자열의 추가, 수정, 삭제 등이 빈번하게 발생할 때에는 적합하지 않습니다.
- 추가로 단순 조회 연산에서는 다른 클래스에 비해 속도가 빠르며, 무결성으로 인해 멀티쓰레드 환경에서 동기화로부터 안전하다는 특징이 있습니다.


# StringBuffer, StringBuilder

- 이를 해결하기 위해 자바에서 도입한 가변성을 가지는 클래스가 바로 StringBuffer와 StringBuilder입니다.

- StringBuilder는 문자열 연산을 위해 클래스 객체를 한 개만 만들고, 길이를 변형시키며 연산을 진행할 수 있습니다.
- 여기서 StringBuffer와 StringBuilder의 차이는 동기화의 지원 유무입니다. StringBuffer는 동기화 키워드를 지원하기 때문에 멀티쓰레드 환경에서 안전하고 StringBuilder는 동기화를 지원하지 않지만 단일쓰레드 환경에서 성능이 더 뛰어나다는 장점이 있습니다.

 

 


# 더 생각해볼 만한 내용

$ String 객체가 관리되는 메모리 영역에 대해 생각해보기
$ String vs StringBuilder의 속도(성능) 차이에 대해 생각해보기

$ String 객체의 메모리 사용 원리?
$ JDK 1.5 버전에서 String을 써도 상관없다?

 

 

# String 객체가 관리되는 메모리 영역에 대해 생각해보기

- String은 클래스이며, 기본타입이 아닌 참조타입이다. 

- 따라서 String 객체는 'Heap 영역'의 String constant pool이라는 곳에서 따로 관리된다.

 * 기본타입은 'stack 영역'에 값이 저장된다. 
 * 메모리(RAM)에서 실행되는 '프로세스'는 code-data-heap-stack 영역으로 나뉜다
 * code에는 소스코드가, data에는 전역변수 및 static 변수가, heap은 런타임에 동적 할당되는 데이터가, stack은 컴파일 타임에 함수호 출시 지역변수 및 매개변수가 저장된다.
 * '멀티프로세스'는 각각 프로세스별로 각각 고유한 [code-data-heap-satck] 영역을 가진다. 프로세스 간에 데이터 전달이 필요할 경우 'IPC'를 통해 해결한다.
 * 'IPC'는 원칙적으로 독립적인 주소 공간을 갖는 프로세스 간에 주소 공간을 참조를 위한 방식으로 대표적으로 '공유메모리 방식'과 '메시지전달 방식'이 있다.
 * '공유메모리 방식'은 메모리상에 shared memory를 확보하여 read/write를 통해 통신하여 속도가 빠른 장점이 있으나 동기화 문제가 야기될 수 있다.
 * '메시지전달 방식'은 커널을 통해 send/receive 연산으로 데이터를 전달하는 방식으로 속도는 느리지만 동기화 문제로부터 안전하다

 

# String vs StringBuilder의 속도(성능) 차이에 대해 생각해보기

- 속도 측정 및 비교 (옛날 글 주의) : https://drsggg.tistory.com/83

 

자바에서 주로 사용하는 기능들의 속도 측정 및 비교(TimeMills와 nanoTime의 차이 / System.out.println()

목차 1. TimeMillis 와 nanoTime 의 차이 2. System.out.println() 의 문제점 3. String 과 StringBuffer 의 차이 4. 기본 자료구조 - Set & List & Map 1. TimeMillis 와 nanoTime 의 차이 2. System.out.pri..

drsggg.tistory.com

- 속도 차이의 원인은 결국 가비지 컬렉터 때문입니다.
  1. String 클래스의 객체가 재할당 될 때마다 새로운 객체를 생성하게 되고
  2. 문자열 연산이 많아질수록 오버헤드가 발생하게 되며
  3. 이때 GC가 수행되면서 성능 저하(속도)

 

* JVM, GC, 자바의 구동원리 : https://drsggg.tistory.com/562

 

JVM, GC, 자바의구동원리

공부한것들을 정리하는 블로그 입니다. JVM, GC, 자바의구동원리 본문 JAVA 공부 JVM, GC, 자바의구동원리 호 두 2022. 5. 17. 23:56 Prev 1 ··· 6 7 8 9 10 11 12 13 14 ··· 355 Next

drsggg.tistory.com

 

 

# String 객체의 메모리 사용 원리?

  1. String 클래스의 객체는 재할당 될 때마다 메모리 점유량이 늘어난다
     ex) String은 address=100 -> 150 -> 200 순으로 길이가 변경될 경우 '주소'도 재할당 되면서 변경됨
     ex) StringBuilder는 address=100 에서 길이가 변경되어도 '주소'는 재할당 되지 않고 진행
  2. 메모리 부족시 GC작업에 의해 추가적인 자원이 소모된다
     - 오버헤드가 발생한다고 표현한다. 
     ex) 문자열 연산이 많아질수록 -> 계속적으로 문자열을 만드는 오버헤드가 발생
 
- 결국 성능 저하는 가비지컬렉터 때문이다.
- 자바의 성능을 향상시키기 위해서는 GC를 얼마나 적게 돌릴 것인지를 고려해야 한다


# JDK 1.5 버전에서 String을 써도 상관없다?

- JDK 1.5 버전 이후로는 컴파일 단계에서 String 객체를 사용하여도 내부적으로는 StringBuilder로 컴파일되도록 변경되었습니다.
- 따라서 String 클래스를 활용하여도 StringBuilder와 성능상으로 차이가 없습니다.
- 단, 반복 루프를 사용하여 문자열을 더할 경우에는 객체를 계속 추가한다는 사실에는 변함이 없기 때문에 오버헤드가 발생할 수 있습니다.
- 따라서 String 클래스를 사용하는 대신, thread-safe 해야 한다면 StringBuffer를 thread-safe를 고려하지 않아도 된다면 StringBuilder를 사용할 수 있습니다.

 

 

 

 

 

반응형

'JAVA > 공부' 카테고리의 다른 글

자바의신 부록, 요약본  (0) 2022.08.01
자바의신 20장 java.lang  (0) 2022.07.12
자바의신 19장 JVM  (0) 2022.07.12
링크) 왜 Enum을 사용할까?  (0) 2022.05.26
추상클래스와 인터페이스  (0) 2022.05.18
JVM, GC, 자바의구동원리  (0) 2022.05.17
JVM에 대하여 정리  (0) 2022.04.30
좋은 객체 지향 설계의 5가지 원칙(SOLID)  (0) 2022.04.24
Comments