Java에서는 문자열을 사용할 때 String, StringBuffer, StringBuilder 이렇게 3개의 class를 사용한다. 이 글에서는 이 세가지 class의 차이를 알아볼 것이다.
String
앞선 포스팅에 언급했듯 String은 reference type이자 immutable이며 다음 과정을 거쳐 address를 받아온다.
- literal로 할당 시 intern() method를 호출한다.
- string constant pool에 해당하는 값이 있으면 그 address를 받아온다.
- string constant pool에 해당하는 값이 없으면 그 값을 string constant pool에 할당하고 address를 받아온다.
- new String()과 같이 constructor로 할당 시 heap에 새 String object를 생성한다.
immutable이므로 해당값에 다른 문자열을 추가하거나 새로 할당해도 원래 있던 String은 유지되고, 대체된 새로운 String을 참조하며 이 과정에서 overhead가 발생한다. 따라서 string constant pool에 할당하든 heap에 할당하든 관계없이 모두 GC에 의해 관리되어야 하기 때문에 연산이 여러 번 이루어 질 때 성능이 좋지 않다.
Java 8부터 String Constant Pool은 Heap으로 옮겨졌다.
또한 immutable이기 때문에 multi-thread에서 synchronization을 신경쓰지 않아도 되므로 thread-safe이다.
String의 내부 구현
package java.lang;
public final class String implements java.io.Serializable, java.lang.Comparable, java.lang.CharSequence {
// ...
private final byte[] value;
// ...
}
String에 저장되는 문자열을 byte의 array 형태로 저장되며, final로 선언되었기 때문에 immutable하다는 것을 알 수 있다.
StringBuffer, StringBuilder
StringBuffer와 StringBuilder는 모두 buffer를 이용해 문자열을 관리하며, mutable이다. 따라서 new keyword로 object를 생성한 후 replace든, erase든, append든 해당 값에 직접 접근해 값을 변경할 수 있다. 따라서 문자열 연산이 여러 번 이루어져도 추가적인 object를 생성하지 않기 때문에 성능이 좋다.
차이점은, StringBuffer는 Synchronized keyword가 존재하며 multi-thread 환경에서 synchronization을 보장할 수 있지만, StringBuilder는 synchronization을 보장하지 않는다. 따라서 StringBuilder는 single-thread 환경에서 StringBuffer보다 조금 더 빠르다.
정리
항상 그렇듯 모든 library의 사용은 case-by-case이다.
String은 연산 시 새로운 memory를 계속 할당 받아야 하므로 느리다. 반면 StringBuffer와 StringBuilder는 dynamic array를 이용해 string을 관리하므로 연산 시 매번 memory를 할당할 필요가 없으므로 빠르다. 따라서 문자열이 변하지 않는 것을 보장할 수 있을 때는 String을, 변하거나 연산을 해야 하는 경우에는 thread 환경에 따라 StringBuffer나 StringBuilder를 사용하는 것이 좋을 것이다.
String | StringBuffer | StringBuilder | |
저장되는 위치 | literal 선언 시 constant pool(heap) constructor 사용 시 heap |
heap | heap |
Immutable? | immutable | mutable | mutable |
Thread Safe? | Thread-Safe | Thread-Safe | Unsafe |
'Development > Java' 카테고리의 다른 글
[Java] Collection (0) | 2023.03.06 |
---|---|
[Java] Multi Thread (0) | 2023.03.04 |
[Java] Primitive Wrapper Class (0) | 2023.03.04 |
[Java] Generic (0) | 2023.03.02 |
[Java] Java Virtual Machine (0) | 2023.03.01 |