자바 String 의 intern 방법 은 장면 예제 를 사용 합 니 다.

intern 방법 을 말 하기 전에 자바 의 상수 탱크 분 류 를 간단하게 살 펴 보 자.
상수 탱크 의 분류
자바 의 상수 탱크 는 Class 상수 탱크,운행 시 상수 탱크 와 문자열 상수 탱크 로 나 눌 수 있다.
1.Class 파일 상수 탱크
Class 파일 에는 버 전,필드,방법,인터페이스 등 설명 정보 외 에 도 상수 풀(Constant Pool Table)이 있 으 며,컴 파일 기간 에 생 성 된 다양한 글자 의 양 과 기호 인용 을 저장 하 는 데 사용 된다.
이른바 글자 의 양 이 우리 가 평소에 말 하 는 상수 와 유사 하 다 는 것 은 주로 다음 과 같은 두 가 지 를 포함한다.
  • 텍스트 문자열,예 를 들 어 String a="aa".그 중에서"aa"는 바로 글자 의 양 이다
  • final 에 의 해 수 정 된 변수..
  • 기호 인용 은 다음 과 같은 형식 을 포함한다.
    4.567917.클래스 와 인터페이스 와 전체 제한 이름:예 를 들 어 String 과 같은 종류 에 대한 전체 제한 이름 은 자바/lang/string 입 니 다4.567917.필드 의 이름과 설명자:필드 란 클래스 나 인터페이스 에서 설명 하 는 변수 로 클래스 급 변수 와 인 스 턴 스 급 변 수 를 포함한다
  • 방법의 이름과 설명자:설명자 란 방법의 매개 변수 유형+반환 값 형식 에 해당 합 니 다
  • 2.런 타임 풀
    클래스 로 더 는 해당 하 는 Class 파일 을 불 러 올 것 이라는 것 을 알 고 있 습 니 다.위 에 소 개 된 Class 파일 상수 탱크 의 데 이 터 는 클래스 로 더 된 후 방법 영역 에 들 어 갈 때 상 당량 탱크 에 들 어 갈 것 입 니 다.운행 시 상 당량 탱크 는 전역 적 으로 공유 되 며,여러 종류 가 하나의 운행 시 상 당량 탱크 를 공용 한다.운행 시 상 당량 탱크 는 방법 구역 에 존재 합 니 다.
    3.문자열 상수 탱크
    이름 을 보면 문자열 상수 탱크 는 문자열 을 저장 하 는 데 사 용 됩 니 다.즉,Class 파일 상수 탱크 의 텍스트 문자열 은 클래스 로 딩 할 때 문자열 상수 탱크 에 들 어 갑 니 다.
    그 문자열 상수 탱크 와 운행 상수 탱크 는 어떤 관계 입 니까?위 에서 말 했 듯 이 Class 파일 상수 탱크 의 문 자 는 클래스 로 딩 한 후에 런 타임 풀 에 들 어 갑 니 다.그 중에서 문자 의 양 에 도 텍스트 문자열 이 포함 되 어 있 습 니 다.이 문 자 를 통 해 문자열 상수 탱크 가 런 타임 풀 에 존재 하고 방법 구역 에 존재 한 다 는 것 을 알 수 있 습 니 다.
    그러나 JDK 1.7 에 이 르 렀 을 때 문자열 상수 탱크 는 방법 영역 에서 옮 겨 져 더미 로 옮 겨 졌 다.또한 우리 가 주의해 야 할 것 은 문자열 상수 탱크 에 저 장 된 것 은 문자열 자체 가 아니 라 문자열 대상 의 참조 입 니 다.
    프로그램 이 실 행 될 때 상수 풀 에 상수(예 를 들 어 intern 방법 호출)를 수 동 으로 추가 하지 않 으 면 jvm 은 상수 풀 에 상수 풀 을 자동 으로 추가 하지 않 습 니 다.
    String 의 intern 방법
    String 방법의 역할 은 문자열 상수 탱크 에 인용 이 존재 하 는 지 판단 하 는 것 입 니 다.이 인용 이 가리 키 는 문자열 대상 은 현재 대상 과 같 습 니 다(equals 방법 으로 판단 합 니 다).이 인용 이 존재 하지 않 으 면 문자열 대상 을 만 들 고 인용 을 문자열 상수 탱크 에 저장 합 니 다.
    다음은 열 을 들 어 이 해 를 깊이 있 게 돕 겠 습 니 다.
    
    //    JDK 8
    
    //s1          "    "
    String s1 = "    ";
    //s2           "    "
    String s2 = "    ";
    //s3         
    String s3 = new String("    ");
    //             "    "   ,        
    String s4 = s3.intern();
    
    //         
    String s5 = new String("ddd");
    //         "ddd"   ,    "ddd"  ,          
    String s6 = s5.intern();
    //         
    String s7 = new String("ddd");
    //        "ddd"   ,    
    String s8 = s7.intern();
    
    System.out.println("s1==s2:"+(s1==s2));
    System.out.println("s1==s3:"+(s1==s3));
    System.out.println("s1==s4:"+(s1==s4));
    
    System.out.println("s5==s6:"+(s5==s6));
    System.out.println("s6==s8:"+(s6==s8));
    System.out.println("s7==s8:"+(s7==s8));
    돌아 온 결 과 는 다음 과 같다.
    s1==s2:true
    s1==s2:false
    s1==s2:true
    s5==s6:false
    s6==s8:true
    s7==s8:false
    intern 방법 사용 필드
    우 리 는 아래 의 이 방법 을 보 자.
    
    public class Person{
      String name;
      public void setName(String name)
      {
        this.name = name
      }
    }
    현재 Person 대상 이 모두 샤 오 밍 이 라 고 한다 면 이 Person 대상 들 은 서로 다른 문자열 대상 을 참조 할 것 입 니 다.

    만약 우리 가 이 방법 을 개선 한다 면:
    
    public class Person{
      String name;
      public void setName(String name)
      {
        this.name = name.intern();
      }
    }
    그러면 대상 의 인용 구 조 는 다음 그림 과 같다.

    이렇게 하면 여러 문자열 대상 의 공간 을 분명히 절약 할 수 있다.나 는 테스트 프로그램 을 하나 썼 다.
    
    public class JavaTest {
    
      public static void main(String[] args) throws Exception {
       //        
       String s = "c...c";
       List<Person> personList = new ArrayList<>();
    
       int count = 100000;
        for (int i = 0; i < count; i++) {
          Person p = new Person();
          p.setName(new String(s));
          //      
          personList.add(p);
          System.out.println(i);
        }
       System.out.println("success...");
      }
    
      public static class Person{
        private String name;
        public void setName(String name) {
          this.name = name;
        }
      }
    
    }
    프로그램 이 메모 리 를 빨리 소모 할 수 있 도록,나 는 메모 리 를 5M 로 설정 했다.
    
    -Xms5m -Xmx5m
    결 과 는 다음 과 같다.
    
    ...
    93889
    93890
    Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
    	at com.csx.demo.spring.boot.util.JavaTest.main(JavaTest.java:15)
    9w 이상 의 대상 을 만 들 때 OutOf Memory Error 오류 가 발생 했 습 니 다.
    Person 의 set 방법 을 조정 하고 실행 하 겠 습 니 다.
    
    public static class Person{
      private String name;
      public void setName(String name) {
        this.name = name.intern();
      }
    }
    99997
    99998
    99999
    success...
    순조롭게 집행 하여 완성 하 다.
    이상 은 자바 String 의 intern 방법 사용 장면 예제 의 상세 한 내용 입 니 다.자바 String 의 intern 방법 에 관 한 자 료 는 다른 관련 글 을 주목 하 세 요!

    좋은 웹페이지 즐겨찾기