자바 프로 그래 밍 에서 의 성능 최적화 어떻게 실현 합 니까?

String 은 우리 가 가장 자주 사용 하 는 대상 유형 으로서 그 성능 문 제 는 가장 무시 되 기 쉽다.자바 의 중요 한 데이터 형식 으로서 메모리 에서 공간 을 차지 하 는 대상 입 니 다.문자열 을 어떻게 효율적으로 사용 하 는 지 는 우리 가 시스템 의 전체적인 성능 을 향상 시 키 는 데 도움 을 줄 수 있다.
현재 우 리 는 String 대상 의 실현,특성 과 실제 사용 에서 의 최적화 등 몇 가지 측면 에서 착안 하여 다음 의 String 의 성능 최 적 화 를 깊이 이해한다.
그 전에 먼저 문 제 를 봅 시다.세 가지 방식 으로 세 개의 대상 을 만 든 다음 에 두 개의 일치 하 는 결 과 는 무엇 입 니까?답 은 마지막 에 발표 하도록 남 겨 두 었 다.

String str1 = "abc";
String str2 = new String("abc");
String str3 = str2.intern();
System.out.println(str1 == str2);
System.out.println(str2 == str3);
System.out.println(str1 == str3);
  
String 대상 은 어떻게 이 루어 졌 나 요?
자바 에서 String 대상 에 대해 대량의 최적화 를 하여 메모리 공간 을 절약 하고 String 대상 의 성능 을 향상 시 켰 다.다음 그림 은 자바 6->자바 9 String 대상 속성의 변화 입 니 다.

String 의 속성 에 다음 과 같은 변화 가 있 음 을 알 수 있 습 니 다.
4.567917.자바 6 및 이전 버 전에 서 String 대상 은 char 배열 을 패키지 하여 실현 한 대상 입 니 다.주로 char 배열,오프셋 오프셋 오프셋,문자 수량 count,해시 값 hash 가 있 습 니 다.String 대상 은 offset 과 count 속성 을 통 해 char 배열 을 찾 고 문자열 을 가 져 옵 니 다.이렇게 하면 배열 대상 을 효율적으로 공유 하고 메모리 공간 을 절약 할 수 있 으 나 메모리 누 출 이 발생 하기 쉽다.
자바 7 부터 자바 8 버 전 까지 자바 가 String 에 대해 변 화 를 주 었 습 니 다.String 클래스 에는 더 이상 offset 과 count 두 속성 이 없습니다.이렇게 하면 String 대상 이 사용 하 는 메모 리 를 줄 일 수 있 고 String.substring 방법 도 char[]를 공유 하지 않 아 발생 할 수 있 는 메모리 누 출 문 제 를 해결 할 수 있 습 니 다.
4.567917.자바 9 버 전부터 char[]를 by te[]로 바 꾸 고 새로운 속성 coder 를 추 가 했 습 니 다.coder 는 인 코딩 형식의 표지 입 니 다왜 이렇게 고 쳐 요?
우 리 는 하나의 char 문자 가 16 비트,2 바이트 라 는 것 을 안다.이런 상황 에서 단일 바이트 의 문 자 를 저장 하면 낭비 하기 쉽다.JDK 1.9 의 String 클래스 는 메모리 공간 을 절약 하기 위해 8 비트,1 바이트 의 byte 배열 로 문자열 을 저장 합 니 다.
coder 속성의 역할 은 문자열 의 길 이 를 계산 하거나 index Of()를 사용 할 때 이 필드 에 따라 문자열 의 길 이 를 어떻게 계산 하 는 지 판단 하 는 것 입 니 다.coder 속성 값 은 기본적으로 0 과 1 두 개의 값 이 있 고 0 은 Latin-1(단일 바이트 인 코딩)을 대표 하 며 1 은 UTF-16 을 대표 합 니 다.String 이 문자열 에 Latin-1 만 포함 된다 고 판단 하면 coder 값 은 0 을 취하 고 그렇지 않 으 면 1 입 니 다.
String 대상 의 불변성
String 의 원본 코드 를 보면 String 클래스 는 final 키워드 로 수식 되 고 변수 char 배열 도 final 로 수식 되 어 있 음 을 알 수 있 습 니 다.
하나의 클래스 가 final 에 의 해 수 정 된 것 은 이 클래스 를 계승 할 수 없 음 을 의미 합 니 다.char[]는 private 와 final 에 의 해 수 정 된 것 으로 String 대상 을 변경 할 수 없습니다.스 트 링 대상 의 불변성 이 라 고 합 니 다.즉,String 대상 이 생 성 되면 더 이상 바 꿀 수 없습니다.
이렇게 하면 좋 은 점 이 어디 에 있 습 니까?  
첫째,String 대상 의 안전성 을 보장 합 니 다.String 대상 이 가 변 적 이 라 고 가정 하면 String 대상 은 악의 적 으로 수 정 됩 니 다.
둘째,hash 속성 치가 자주 변경 되 지 않도록 유일 성 을 확보 합 니 다.HashMap 용기 와 유사 해 야 키-value 캐 시 기능 을 실현 할 수 있 습 니 다.
셋째,문자열 상수 탱크 를 실현 할 수 있 습 니 다.자바 에 서 는 보통 문자열 대상 을 만 드 는 두 가지 방식 이 있 습 니 다.하 나 는 문자열 상수 로 만 드 는 것 입 니 다.예 를 들 어 String str="abc";다른 하 나 는 문자열 상수 가 new 형식 으로 생 성 되 는 것 입 니 다.예 를 들 어 String str=new String("abc").
코드 에서 첫 번 째 방식 으로 문자열 대상 을 만 들 때 JVM 은 먼저 이 대상 이 문자열 상수 탱크 에 있 는 지 확인 하고 이 대상 의 인용 을 되 돌려 주지 않 으 면 새 문자열 이 상수 탱크 에 생 성 됩 니 다.이 방식 은 같은 값 의 문자열 대상 의 중복 생 성 을 줄 이 고 메모 리 를 절약 할 수 있 습 니 다.
두 번 째 방식 은 우선 클래스 파일 을 컴 파일 할 때'abc'상수 문자열 을 상수 구조 에 넣 고 클래스 로 딩 할 때'abc'는 상수 풀 에서 만 듭 니 다.그리고 new 를 호출 할 때 JVM 명령 은 String 의 구조 함 수 를 호출 하고 상수 탱크 의'abc'문자열 을 참조 하여 메모리 에 String 대상 을 만 들 고 마지막 으로 str 는 String 대상 을 참조 합 니 다.
  
String 대상 최적화
1.초대형 문자열 을 만 드 는 방법
프로 그래 밍 과정 에서 문자열 의 연결 은 매우 흔 하 다.String 대상 을 더 하면 우리 가 원 하 는 문자열 을 맞 추 면 여러 대상 이 생 길 수 있 습 니까?예 를 들 어 다음 코드:

String str = "ab" + "cd" + "ef";
분석 코드 를 통 해 알 수 있 듯 이 먼저 ab 대상 을 생 성하 고 abcd 대상 을 생 성 하 며 마지막 으로 abcdef 대상 을 생 성 합 니 다.이론 적 으로 말 하면 코드 는 매우 비효 율 적 이다.
하지만 실제로는 한 대상 만 생 성 되 는 것 을 발견 할 수 있다.왜 일 까?컴 파일 할 때 컴 파일 러 는 자동 으로 코드 를 최적화 시 켜 마지막 에 하나의 대상 만 얻 을 수 있 도록 합 니 다.
문자열 상수 의 누적 을 진행 하면 어떤 결과 가 나 올 까?

String str = "abcdef";
for (int i = 0; i < 100; i++) {
   str = str + i;
 }
위의 코드 를 컴 파일 한 후에 컴 파일 러 역시 코드 를 최적화 시 켰 고 문자열 을 연결 할 때 StringBuilder 를 사용 하면 효율 을 높 일 수 있 습 니 다.위의 코드 는 아래 와 같이 변 했다.

String str = "abcdef";
for (int i = 0; i < 100; i++) {
  str = (new StringBuilder(String.valueOf(str))).append(i).toString();
}
요약:문자열 의 조합 으로+번 호 를 사용 하 더 라 도 컴 파일 러 에 의 해 StringBuilder 로 최적화 할 수 있 습 니 다.그러나 순환 할 때마다 새로운 StringBuilder 인 스 턴 스 를 만 들 면 시스템 의 성능 이 떨 어 집 니 다.그래서 평소에 문자열 을 맞 출 때 StringBuilder 를 사용 하여 성능 을 향상 시 키 는 것 을 보 여 주 는 것 을 권장 합 니 다.다 중 스 레 드 프로 그래 밍 을 할 때 String 대상 의 연결 은 스 레 드 안전 과 관련 되 어 StringBuffer 를 사용 할 수 있 습 니 다.그러나 StringBuffer 는 스 레 드 가 안전 하고 잠 금 경쟁 과 관련 되 기 때문에 성능 적 으로 StringBuilder 보다 떨 어 질 수 있 습 니 다.
2.어떻게 String.intern 을 사용 하여 메모 리 를 절약 합 니까?
일부 데이터 에 대해 서 는 데이터 의 양 이 매우 많 지만 동시에 대부분 겹 치 는 것 이 있 는데 어떻게 처리 해 야 합 니까?
구체 적 인 방법 은 값 을 할당 할 때마다 String 의 intern 방법 을 사용 하고 상수 탱크 에 같은 값 이 있 으 면 이 대상 을 반복 해서 사용 하여 대상 의 인용 을 되 돌려 주 는 것 이다.그러면 처음에 대상 을 회수 할 수 있 고 그러면 데이터 의 양 이 대폭 줄어든다.
우 리 는 다시 하나의 예 를 보 자.

String a = new String("abc").intern();
String b = new String("abc").intern(); 
if (a == b) {
   System.out.println("a == b");
}
출력 결 과 는:a==b 입 니 다.
문자열 상수 탱크 에 기본적으로 대상 을 상수 탱크 에 넣 습 니 다.문자열 변수 에서 대상 은 항상 메모리 더미 에 만 들 고 상수 탱크 에 문자열 대상 을 만 들 며 메모리 더미 대상 에 복사 하고 메모리 대상 참조 로 되 돌려 줍 니 다.
intern 방법 을 호출 하면 문자열 상수 탱크 에 이 대상 과 같은 문자열 이 있 는 지 확인 하고 없 으 면 상수 탱크 에 이 대상 을 추가 하고 이 대상 에 게 참조 하도록 되 돌려 줍 니 다.있 으 면 상수 탱크 의 문자열 참조 로 돌아 갑 니 다.메모리 에 있 는 대상 은 인용 이 가리 키 지 않 아 쓰레기 수 거 기 를 통 해 회수 된다.
3.문자열 의 분할 방법 을 어떻게 사용 합 니까?
spilt()방법 은 정규 표현 식 을 사용 하여 강력 한 분할 기능 을 실현 하 였 으 며,정규 표현 식 의 성능 은 매우 불안정 하 며,잘못 사용 하면 역 추적 문 제 를 일 으 켜 CPU 가 높 아 지지 않 을 수 있 습 니 다.
따라서 spilt 방법 을 신중하게 사용 해 야 합 니 다.spilt()방법 대신 String.index Of()방법 으로 문자열 의 분할 을 완성 할 수 있 습 니 다.만약 에 수 요 를 만족 시 키 지 못 한다 면 spilt 방법 을 사용 할 때 역 추적 문 제 를 중시 하면 됩 니 다.
총결산
위의 서술 을 통 해 우 리 는 String 문자열 의 성능 을 최적화 시 켜 전체 시스템 의 성능 을 향상 시 킬 수 있다 는 것 을 깨 달 았 다.이 이론 을 바탕 으로 자바 버 전 은 교체 과정 에서 구성원 변 수 를 계속 변경 하고 메모리 공간 을 절약 하 며 String 성능 을 최적화 시 켰 다.
String 대상 의 불변성 도 언급 했 습 니 다.바로 이 기능 이 문자열 상수 탱크 를 실현 하고 같은 값 의 문자열 대상 의 중복 생 성 을 줄 여 메모 리 를 절약 합 니 다.또한 이 특성 때문에 긴 문자열 의 연결 을 할 때 문자열 의 연결 성능 을 향상 시 키 기 위해 StringBuilder 를 사용 하 는 것 을 표시 해 야 합 니 다.마지막 으로 최적화 에 있어 서 우 리 는 intern 방법 을 사용 하여 변수 문자열 대상 이 상수 탱크 에서 같은 값 의 대상 을 중복 사용 하여 메모 리 를 절약 할 수 있다.
마지막 으로 위의 그 문제 의 결 과 를 발표 합 니 다.
  false、false、true。
그 중에서 String str 1="abc";문자열 상수 탱크 에 abc 를 글자 크기 로 만 듭 니 다.
  String str2 = new String("abc");new 대상 을 통 해 문자열 대상 을 만 들 고 주 소 를 참조 하여 메모리 에 저장 하 며 abc 는 문자열 상수 탱크 에 저장 하기 때문에 false 입 니 다.
  String str3 = str2.intern();intern()방법 을 호출 하면 상수 탱크 의 데 이 터 를 되 돌려 줍 니 다.str 3 는 이때 상수 탱크 의 abc 를 가리 키 며 str 1 의 방식 과 같 기 때문에 true 입 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기