String 객체는 자바에서 제일 많이 쓰이는 객체이다.
Java String Pool - JVM에 의해 String 객체들이 저장되는 특별한 메모리 공간이다.
String interning
String interning은 JVM이 동일한 문자열 하나만을 pool에 저장하여 메모리 사용을 최적화하는 것을 말한다.
String 변수를 만들 때, JVM은 pool에서 동일한 문자열이 있는지 찾아서, 동일한 문자열이 pool에 존재하면 새로운 메모리를 사용하여 변수를 만들지 않고 메모리 주소를 참조하게 해준다.
문자열을 pool에서 찾을때는 해시 알고리즘을 사용하기 때문에 매우 빠른 속도로 찾을 수 있다. O(1)
만약, 동일한 문자열이 없다면 새로운 String 객체를 만들어서 String pool에 넣어준다.
String string1 = "java";
String string2 = "java";
Assertions.assertThat(string1).isSameAs(string2);
System.out.println(string1 == string2); // True
System.outp.println(string1.equals(string2)); // True
isSameAs : 두 객체가 같은 reference인지 비교한다. (주소값)
isEqualTo : 두 객체가 같은 value인지 비교한다.
생성자를 사용하여 String 객체 생성
String 객체를 생성자를 사용하여 생성하면 Java compiler는 새로운 객체를 생성하여 JVM의 힙 메모리 영역에 저장한다. 그렇기 때문에, 모든 String 객체는 다른 메모리 공간을 차지하게 된다.
String string1 = "JAVA";
String string2 = new String("JAVA");
Assertions.assertThat(string1).isNotSameAs(string2);
System.out.println(string1 == string2); // False
System.outp.println(string1.equals(string2)); // True
그렇기 때문에, 가능하다면 자바에서 String을 생성할때는 literal 방식("JAVA")으로 생성하는 것이 효율적이다.
직접 String객체를 interning 하기
String 객체의 intern() 함수를 사용하면 직접 String 객체를 intern 하여 사용할 수 있다.
String first = "new String";
String second = first.intern();
String third = new String("new String");
Assertions.assertThat(first).isSameAs(second);
System.out.println(first == second); // True
System.out.println(first == third); // False
System.out.println(second == third); // False
JAVA7 이후
Java 7 부터 Java String Pool이 Heap Space로 옮겨 지면서 garbage collector의 대상이 되었다.
Java 7 이전에는 String Pool이 PermGen(Permanent Generation) 영역에 존재하여 GC의 대상이 되지 못하였다. PermGen 영역은 클래스의 메타데이터를 담는 곳으로 제한된 크기를 가지고 있어서, 너무 많은 String 객체를 intern하면 OutOfMemory 에러를 발생시킬 수 있다.
참조
String 객체는 자바에서 제일 많이 쓰이는 객체이다.
Java String Pool - JVM에 의해 String 객체들이 저장되는 특별한 메모리 공간이다.
String interning
String interning은 JVM이 동일한 문자열 하나만을 pool에 저장하여 메모리 사용을 최적화하는 것을 말한다.
String 변수를 만들 때, JVM은 pool에서 동일한 문자열이 있는지 찾아서, 동일한 문자열이 pool에 존재하면 새로운 메모리를 사용하여 변수를 만들지 않고 메모리 주소를 참조하게 해준다.
문자열을 pool에서 찾을때는 해시 알고리즘을 사용하기 때문에 매우 빠른 속도로 찾을 수 있다. O(1)
만약, 동일한 문자열이 없다면 새로운 String 객체를 만들어서 String pool에 넣어준다.
String string1 = "java";
String string2 = "java";
Assertions.assertThat(string1).isSameAs(string2);
System.out.println(string1 == string2); // True
System.outp.println(string1.equals(string2)); // True
isSameAs : 두 객체가 같은 reference인지 비교한다. (주소값)
isEqualTo : 두 객체가 같은 value인지 비교한다.
생성자를 사용하여 String 객체 생성
String 객체를 생성자를 사용하여 생성하면 Java compiler는 새로운 객체를 생성하여 JVM의 힙 메모리 영역에 저장한다. 그렇기 때문에, 모든 String 객체는 다른 메모리 공간을 차지하게 된다.
String string1 = "JAVA";
String string2 = new String("JAVA");
Assertions.assertThat(string1).isNotSameAs(string2);
System.out.println(string1 == string2); // False
System.outp.println(string1.equals(string2)); // True
그렇기 때문에, 가능하다면 자바에서 String을 생성할때는 literal 방식("JAVA")으로 생성하는 것이 효율적이다.
직접 String객체를 interning 하기
String 객체의 intern() 함수를 사용하면 직접 String 객체를 intern 하여 사용할 수 있다.
String first = "new String";
String second = first.intern();
String third = new String("new String");
Assertions.assertThat(first).isSameAs(second);
System.out.println(first == second); // True
System.out.println(first == third); // False
System.out.println(second == third); // False
JAVA7 이후
Java 7 부터 Java String Pool이 Heap Space로 옮겨 지면서 garbage collector의 대상이 되었다.
Java 7 이전에는 String Pool이 PermGen(Permanent Generation) 영역에 존재하여 GC의 대상이 되지 못하였다. PermGen 영역은 클래스의 메타데이터를 담는 곳으로 제한된 크기를 가지고 있어서, 너무 많은 String 객체를 intern하면 OutOfMemory 에러를 발생시킬 수 있다.
참조