[Java] - String, StringBuilder,StringBuffer

링딩·2023년 4월 10일
0

Computer Science

목록 보기
29/49




String, StringBuilder,StringBuffer


1. String?

String 클래스는 불변 객체로 String 클래스의 문자열을 저장하는 char[]을 보면 final로 선언되어 있고, 해당 배열을 재할당하는 코드는 존재하지 않는다.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. **/
    private final char value[];
    ...
}

즉, 한 번 할당한 문자열을 중간에 변경할 수는 없기 때문에 우리는 매번 더하기 연산을 통하여 문자를 이어 붙여 매번 수정할 때마다 새로운 객체를 생성하여 재할당을 시킨다.😥

Q. 뭐가 문제일까?🤔

  • 성능이 떨어진다.
  • 반복적으로 문자열을 이어 붙이다 보면 Heap 영역에서 참조를 잃은 문자열 객체가 계속해서 쌓이게 된다.

...
물론, 나중에 GC에 의해 수거가 되지만 메모리 관리 측면에서 이러한 코드는 결코 좋은 코드라고 할 수 없다. 또한 계속해서 객체를 생성하므로 연산 속도 측면에서도 성능이 떨어질 수 밖에 없다.

그렇다면 String Pool은?

1-2. String Pool

Q. String이랑 String Pool이 어떻게 다르단 건가?

String Pool

= 연산자를 통해 값을 String에 대입하면 Heap 영역 내에 있는 String Pool이라는 공간에 문자열이 저장된다.

Heap에 저장...

new 연산자를 통해 String을 만들면 String Pool이 아닌 일반 Heap 영역 어딘가에 저장된다.

둘다 Heap 영역에 저장되는 것은 동일한데, String Pool에 값이 저장되면 어떠한 이점이 있는 것일까?🤔

  • 전자의 방식을 String literal이라고 하는데, String literal로 생성한 객체는 String Pool의 '메모리 주소'를 가리키게 된다.

    • 그래서 똑같은 String literal 객체가 생성될 경우, 같은 값의 주소를 가리키게 되므로 하나의 메모리를 재사용 할 수 있다.
  • 반면 후자는 일반적인 new 연산자를 통해 객체를 생성하는 방식이므로 String Pool의 해당 값이 있더라도 Heap 영역 내 별도의 메모리를 할당하여 주소를 가리키게 된다.




그럼에도 불구하고 문자열의 변화가 상당히 많아서 String 객체를 많이 생성하면 성능 이슈가 발생한다.
그러므로... String 객체를 하나로 두고, 내부 상태를 변경하는 가변 객체로 만드는 것이 좋은데, Java에서는 StringBuilder와 StringBuffer를 지원한다.

2. StringBuilder

특징

  • 가변 객체
  • 내부 char[] 배열의 사이즈를 조절하여 문자열을 이어 붙이기 때문에 새로운 객체를 최소로 할당할 수 있다.
  • StringBuilder 객체 자체를 새롭게 만드는 것은 아니므로 StringBuilder 객체의 주소는 유지가 된다.
StringBuilder s = new StringBuilder("hello");
System.out.println(s.hashCode());  // 859417998
s.append("world");
System.out.println(s.hashCode());  // 859417998

이럴때 추천 👍

  • 문자열에 이어 붙이는 작업이 많을 경우.



3. StringBuffer

대부분의 메소드에 synchronized가 적용되어 일반적으로 멀티 스레드 환경에서 스레드 안전하게 동작한다.
-> 동기화를 지원하는 StringBuilder라고 생각하면 된다.

Q. String Buider랑 String Buffer의 차이?

String Builder는 동기화를 지원하지 않는다.
그렇기에 멀티쓰레드에서는 적합하지 않으나, 단일 쓰레드에서는 String Buffer보다 훨씬 우수한 성능을 가진다.


어떤 곳에서 쓰면 좋을까요?

세가지의 차이점 정리

출처

devmoony님의 글을 참조하여 작성했습니다.
링크텍스트님의 글을 참조하여 작성했습니다.

profile
초짜 백엔드 개린이

0개의 댓글