developer tip

Java의 문자열 풀에 대한 질문

optionbox 2020. 11. 8. 09:48
반응형

Java의 문자열 풀에 대한 질문


이 질문에 이미 답변이 있습니다.

이 코드를 고려하십시오.

String first = "abc"; 
String second = new String("abc");

new키워드를 사용하면 Java가 abc String다시 생성 됩니다. 일반 힙 또는 String풀에 저장됩니까? String에서 끝나는 s는 몇 개 String입니까?


new키워드 를 사용하면 String개체가 생성됩니다. 개체는 항상 힙에 있습니다. 문자열 풀은 힙과 분리 된 별도의 메모리 영역이 아닙니다.

문자열 풀은 캐시와 같습니다. 이렇게하면 :

String s = "abc";
String p = "abc";

Java 컴파일러는 하나의 String객체 만 만들 수있을만큼 똑똑 s하고 p둘 다 동일한 String 객체를 참조합니다. 이렇게하면 :

String s = new String("abc");

그러면 String풀에는 리터럴을 나타내는 하나의 객체가 있고 풀에는 풀이 아닌 객체의 내용 사본을 포함하는 "abc"별도의 String객체 가 있습니다 . 때문에 String자바에서 불변, 당신은이 일을하여 아무것도 확보하지 않는; 호출 new String("literal")은 Java에서 의미가 없으며 불필요하게 비효율적입니다.

당신이 호출 할 수 있습니다 intern()A의 String객체입니다. String풀에 아직없는 경우 개체를 풀에 넣고 풀링 된 문자열에 대한 참조를 반환합니다. (이미 풀에있는 경우 이미있는 개체에 대한 참조 만 반환합니다.) 자세한 내용은 해당 메서드에 대한 API 문서를 참조하세요.

String interning (Wikipedia) 도 참조하십시오 .


에서 바이트 코드 의 첫 임무는 다음과 같습니다

  암호:
   0 : ldc # 2; // 문자열 abc
   2 : astore_1

두 번째는 다음과 같습니다.

   3 : 새로운 # 3; // 클래스 java / lang / String
   6 : 복제
   7 : ldc # 2; // 문자열 abc
   9 : invokespecial # 4; // 메소드 java / lang / String. "":( Ljava / lang / String;) V

따라서 첫 번째는 풀 (위치 # 2)에있는 반면 두 번째는 힙에 저장됩니다.

편집하다

CONSTANT_String_info 인덱스를 U2 (16 비트, 부호 없음) 로 저장하기 때문에 풀은 max 2**16= 65535reference에 포함될 수 있습니다 . 여기에서 JVM의 더 많은 한계 를 걱정하는 경우 .


코드에서 문자열 리터럴을 만들 때마다

예를 들면 :

String str="Hello"; (string literal) 

JVM은 먼저 문자열 리터럴 풀을 확인합니다. 문자열이 이미 풀에있는 경우 풀링 된 인스턴스에 대한 참조가 반환됩니다. 문자열이 풀에 존재하지 않으면 새 String 개체가 인스턴스화되고 풀에 배치됩니다. Java는 문자열이 변경 불가능하고 데이터 손상의 두려움없이 공유 될 수 있기 때문에 이러한 최적화를 수행 할 수 있습니다.


String strObject = new String("Java");

String strLiteral = "Java";

두 표현식 모두 String 객체를 제공하지만 둘 사이에는 미묘한 차이가 있습니다. new () 연산자를 사용하여 String 객체를 만들 때 항상 힙 메모리에 새 객체를 만듭니다. 반면에 "Java"와 같은 문자열 리터럴 구문을 사용하여 객체를 생성하면 문자열 풀 (최근 Java 릴리스에서 힙 공간으로 이동 한 Perm gen 공간의 String 객체 캐시)에서 기존 객체를 반환 할 수 있습니다. , 이미있는 경우.


new String (foo)를 사용해야하는 유일한 경우는 == (이상한 경우)를 중단하거나 foo가 제한된 수명을 가진 훨씬 더 큰 문자열의 하위 문자열 인 경우입니다.

String mystring;
{
   String source = getSomeHeinouslyLargeString();
   mystring = new String(source.substring(1,3));
}

늦었지만 여전히 이것을 발견하는 누군가에게 유용 할 수 있습니다.

String first = "abc";
//One instance object in pool created. Instance variable “first” refers/points to pooled object

String second = new String("abc");    
//One instance object in heap created. Object in pool creation step will be skipped on account of first statement.

따라서 총 2 개의 인스턴스 개체가 생성됩니다. 하나는 풀에, 다른 하나는 힙에

상해

첫 번째 문자열 = "abc";

여기에 "abc"내용이있는 문자열 개체가 풀에 생성되었습니다. 인스턴스 변수“first”는 내용이“abc”인 풀 개체를 가리 킵니다.

String second = new String ( "abc");

여기서 내용이 "abc"인 또 다른 문자열 객체가 힙에 생성됩니다. 인스턴스 변수“second”는 내용이“abc”인 힙 개체를 가리 킵니다. 내용이 "abc"인 풀에서 생성 된 문자열 개체는 첫 번째 문 때문에 건너 뜁니다. 아래 이유.

원인

If assumed prior statement (String first = "abc";) is not there with same content, then generally with “new” keyword, 2 string objects will be created one in heap (outside pool) and the other in pool(a subset area of heap). Also the instance variable "second" should point to heap object only, irrespective of whether the objects is in pool or not.

Now on account of the presence of prior statement (String first = "abc";) with same content as in new String("abc"), only one object (with content "abc") is retained in pool. So on account of 1st statement, the second statement will have only 1 object created instead of 2 and that object is in heap. Pool object creation will be skipped.

//Additional Test on the concept
System.out.println(first==second);  //returns false. Because first points to pool object while second points to heap object. And both objects are different (on account of different memory locations).

second = second.intern();           //After interning, second now points to pool object. Note: intern is used so that reference variable points to pool area object and not heap object. Clearly it is applicable when we use new keyword.

System.out.println(first==second);  //returns true. Because now both first and second objects now points to same pool object.

String first = "abc"; 
String second = new String("abc");

In first case there is only one object will create in Pool. In second case two object will create one in pool (if this is not existing previously in Pool) and one in heap.

When you are passing any value with double quote ex: "abc" you are creating a object in pool and passing it to the string constructor for creating a new object with the same value in heap.

If you saw the string constructor you can see that it accept a string. What is that string? Before creation what is that string object. It's nothing but an object stored in String Constant pool.

참고URL : https://stackoverflow.com/questions/1881922/questions-about-javas-string-pool

반응형