String str = "hell";
str += "o";
str += "!";
이렇게 구하는 경우 당연히 우리는 str이 hello! 가 됨을 알고있다.
그런데 String은 final로 선언된 불변객체라고 하였다.
따라서 이 경우는 실제로
hell , hello , hello!
이렇게 불변의 객체가 하나씩 생기게 되며, 이 중 참조할 내용이 없는 [ hell ], [ hello ] 두 개는 가비지 컬렉션의 대상이 된다.
이는 당연히 자바의 메모리에 있어 좋지 않은 영향을 끼치게 될 것이다.
String 이 불변인 이유??
- 보안
- 여러 참조 변수가 같은 String 객체를 참조하고 있다고 하더라도 안전하다.
- String 객체를 누가 조작할 수가 없기 때문이다.
- String 객체를 이리저리 전달할 때 원본 String 객체가 저장된 주소 자체를 넘겨도 안전하다.
- 전달받은 곳에서 원본 값을 직접 읽을 순 있으나 조작할 수는 없기 때문이다.
불변이 아니라면 보안 검사를 실시한 이후에도 메소드 안에서 String에 대한 참조를 계속 가지고 있기 때문에 문자열을 변경할 수 있다는 가능성이 있다.
2. String 리터럴 사용 시
100개의 같은 문자열이 필요하면 100개 만드는 것이 아니라 하나의 문자열을 스트링 풀안에 두고 계속 참조 , 성능에 좋다
StringBuilder / StringBuffer
StringBuilder / StringBuffer은 이런 String의 문제 해결에 사용된다.
문자열의 추가, 수정, 삭제가 빈번하게 발생할 경우 사용
StringBuffer stringBuffer = new StringBuffer("hello bocho blog");
가 주어졌을 때, !!를 추가하고 싶으면 stringBuffer.append("!!"); 를 해 주면 된다.
이는 StringBuilder / StringBuffer가 String과는 다르게 가변 객체이며, heap영역에서 바로 해당 메모리에 접근할 수 있기 때문이다.
따라서 문자열의 변경이 자주 일어나는 경우 String보다는 StringBuilder / StringBuffer를 사용하는 것이 메모리적으로 이득을 볼 수 있을 것이다.
StringBuilder / StringBuffer 둘의 차이는 ?
StringBuilder - 스레드에 안전하지 않다. / StringBuffer -스레드에 안전
StringBuffer는 모든 메소드에 synchronized가 붙어 있다.
* StringBuffer와 StringBuilder는 성능으로 따졌을 때 2배의 속도차이가 있다고 하지만 참고사이트의 속도 차이 실험 결과 append()연산이 약 1억6천만번 일어날 때 약 2.6초의 속도차이를 보인다고 합니다.
(String은 +연산이 16만번이상 넘어가게 되면 10초이상 걸리면서 못 쓸정도의 성능을 보입니다.)
따라서 문자열연산이 많지만 엄청나게 일어나지 않는 환경이라면 StringBuffer를 사용해서 thread-safe한 것이 좋다는 생각입니다.
String 클래스는 StringBuffer 클래스나 StringBuilder 클래스와 다르게 리터럴을 통해 생성되면 그 인스턴스의 메모리 공간은 절대 변하지 않는다
변경되는 연산이 많다면 스트링끼리 더하는 방식의 빌더와 버퍼가 성능면에서는 좋다
'Java' 카테고리의 다른 글
System.out.println 메소드는 현업에서 절대 쓰지 말아야 하는 이유 (2) | 2023.11.28 |
---|---|
equals와 hashCode (1) | 2023.11.06 |
HashSet 내부 구현 (4) | 2023.10.26 |