Effective 자바 학습(대상 생 성 및 소각)의-불필요 한 대상 생 성 방지

5558 단어 자바
일반적으로 필요 할 때마다 같은 대상 을 만 드 는 것 이 아니 라 가장 좋 은 재 활용 대상 이다.중용 방식 은 빠 르 고 유행한다.대상 이 가 변 적 이지 않 은(immutable)이 라면 처음부터 끝까지 재 활용 할 수 있다.
 
극단 적 인 부정적인 예 로 서 다음 과 같은 문 구 를 고려 합 니 다.
 
String s = new String("hello");

       이 문 구 는 실행 할 때마다 새로운 String 대상 인 스 턴 스 를 만 듭 니 다.그러나 이 대상 들 의 동작 은 모두 불필요 합 니 다.String 구조 에 전 달 된 인자("hello")자체 가 String 인 스 턴 스 이 고 기능 적 으로 구조 기 가 만 든 모든 대상 과 같 습 니 다.이러한 용법 이 하나의 순환 이나 자주 호출 되 는 방법 이 라면 수천 개의 불필요 한 String 인 스 턴 스 대상 을 만 들 수 있 습 니 다.
 
 
 개 선 된 버 전 은 다음 과 같 습 니 다.
 
String s = "hello";

     이 버 전 은 실행 할 때마다 새로운 인 스 턴 스 를 만 드 는 것 이 아니 라 String 인 스 턴 스 만 사용 합 니 다.그리고 그 는 같은 가상 컴퓨터 에서 실행 되 는 모든 코드 에 대해 같은 문자열 의 상수 만 포함 하면 대상 이 다시 사 용 될 것 이 라 고 보증 할 수 있다.
 
 
정적 공장 방법 과 구조 기 를 동시에 제공 하 는 불가 변 류 에 대해 서 는 구조 기 가 아 닌 정적 공장 방법 을 사용 하여 불필요 한 대상 을 만 들 지 않도록 할 수 있다.예 를 들 어 Boolean.valueOf(String)는 거의 항상 Boolean(String)보다 우선 합 니 다.구조 기 는 호출 될 때마다 새로운 대상 을 만 들 고 정적 공장 방법 은 이렇게 하 라 고 요구 하지 않 으 며 실제로 도 이렇게 하지 않 는 다.
 
      변 하지 않 는 대상 을 다시 사용 하 는 것 외 에 도 수정 되 지 않 을 것 으로 알려 진 대상 을 다시 사용 할 수 있다.다음은 미묘 하고 흔히 볼 수 있 는 반면 인 스 턴 스 입 니 다.그 중에서 가 변 적 인 Date 대상 과 관련 되 고 그들의 값 은 계산 되면 변 하지 않 습 니 다.이 종 류 는 하나의 모델 을 만 들 었 다.그 중 한 사람 이 있 고 isBaby Boomer 방법 이 있 는데 이 사람 이'baby boomer(출산 절정 기 에 태 어 난 아이)'인지 검증 하 는 데 사용 된다.다시 말 하면 이 사람 이 그 해 부터 그 해 까지 태 어 났 는 지 확인 하 는 것 이다.
 
public class Person {
	private final Date birthday = null;
	
	public boolean isBabyBoomer(){
		Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
		gmtCal.set(1946, Calendar.JANUARY,1,0,0,0);
		Date boomStart = gmtCal.getTime();
		gmtCal.set(1964, Calendar.JANUARY,1,0,0,0);
		Date boomEnd = gmtCal.getTime();
		
		return birthday.compareTo(boomStart) >= 0 && birthday.compareTo(birthday) < 0;
	}
}

     isBabyBoomer 는 실행 할 때마다 Calendar,TimeZone,Date 인 스 턴 스 두 개 를 만 듭 니 다.필요 하지 않 습 니 다.다음 버 전 은 정적 초기 화 기(initializer)를 사용 하여 효율 이 낮은 상황 을 피 합 니 다.
 
 
public class Person{
	private final Date birthday = null;
	private static Date BOOM_START = null;
	private static Date BOOM_END = null;
	
	static{
		Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
		gmtCal.set(1946, Calendar.JANUARY,1,0,0,0);
		BOOM_START = gmtCal.getTime();
		gmtCal.set(1964, Calendar.JANUARY,1,0,0,0);
		BOOM_END = gmtCal.getTime();
	}
	
	public boolean isBabyBoomer(){
		return birthday.compareTo(BOOM_START) >= 0 && birthday.compareTo(BOOM_END) < 0;
	}
}

      개 선 된 Person 클래스 는 호출 할 때마다 이 인 스 턴 스 를 만 드 는 것 이 아니 라 초기 화 할 때 만 Calendar,TimeZone,Date 인 스 턴 스 를 만 듭 니 다.만약 isBabyBoomer 방법 이 빈번하게 호출 된다 면 이런 방법 은 성능 을 현저히 향상 시 킬 것 이다.
 
 
      앞의 예 에서 토론 한 대상 은 분명히 모두 중 용 될 수 있다.왜냐하면 그들 은 초기 화 된 후에 변 하지 않 기 때문이다.다른 어떤 상황 들 은 항상 이렇게 뚜렷 하지 않다.어댑터 고려 (adapter)의 경우 보기(view)라 고도 부 릅 니 다.어댑터 란 이러한 대상 을 말한다.그의 기능 을 예비 대상 에 게 위탁 하여 등 대상 에 게 대체 할 수 있 는 인 터 페 이 스 를 제공한다.어댑터 는 예비 대상 을 제외 하고 상태 정보 가 없 기 때문에 주어진 대상 의 특정 어댑터 에 대해 여러 개의 어댑터 인 스 턴 스 를 만 들 필요 가 없습니다.
 
      예 를 들 어 Map 인터페이스의 keyset 방법 은 이 Map 대상 의 set 보 기 를 되 돌려 줍 니 다.이 맵 의 모든 키(key)를 포함 합 니 다.굵게 보면 키 세트 를 호출 할 때마다 새로운 Set 인 스 턴 스 를 만들어 야 하 는 것 같 지만 주어진 Map 대상 에 대해 서 는 실제로 키 세트 를 호출 할 때마다 같은 Set 인 스 턴 스 를 되 돌려 줍 니 다.되 돌아 오 는 Set 인 스 턴 스 는 일반적으로 바 꿀 수 있 지만 모든 되 돌아 오 는 대상 은 기능 적 으로 동일 합 니 다.그 중의 한 되 돌아 오 는 대상 이 변화 가 생 겼 을 때 모든 다른 되 돌아 오 는 대상 도 변화 가 생 겨 야 합 니 다.왜냐하면 그들 은 같은 Mao 인 스 턴 스 로 지탱 되 기 때 문 입 니 다.키 세트 보기 대상 을 만 드 는 여러 인 스 턴 스 는 해 가 되 지 않 지만 필요 한 것 은 아 닙 니 다.
 
      JAVA 1.5 발행 버 전에 서 는 자동 포장(autoboxing)이 라 고 부 르 는 여분의 대상 을 만 드 는 새로운 방법 이 있 습 니 다.그 는 프로그래머 가 기본 유형 과 포장 기본 유형 을 혼용 하여 필요 에 따라 자동 으로 포장 하고 분해 할 수 있 도록 합 니 다.자동 포장 은 기본 유형 과 포장 기본 유형 간 의 차 이 를 모호 하 게 만 들 었 으 나 완전히 제거 되 지 는 않 았 다.그들 은 의미 에 있어 서 미묘 한 차이 가 있 고 성능 에 있어 서도 비교적 현저 한 차이 가 있다.다음 절 차 를 고려 하여 그 는 모든 int 의 플러스 를 계산한다.이 를 위해 프로그램 은 long 알고리즘 을 사용 해 야 합 니 다.int 가 크 지 않 기 때문에 모든 int 의 정수 합 계 를 수용 할 수 없습니다.
 
public static void main(String[] args) {
		long sum = 0L;
		for(long i = 0; i < Integer.MAX_VALUE; i++){
			sum += i;
		}
		System.out.println(sum);//2305843005992468481
	}

 
     프로그램 이 계산 한 답 은 정확 하지만 실제 상황 보다 좀 더 느 린 것 은 단지 한 문 자 를 잘못 쳤 기 때문이다.변수 sum 은 log 가 아 닌 Long 으로 밝 혀 졌 습 니 다.프로그램 구조 가 약 2 의 31 차방 의 여분의 Long 인 스 턴 스(대략 Long sum 에 long 을 추가 할 때마다 하나의 인 스 턴 스 를 구성 합 니 다)를 의미 합 니 다.sum 의 성명 을 log 로 바 꾸 면 효율 이 훨씬 빠 를 것 이 분명 합 니 다.주의:포장 류 가 아 닌 기본 유형 을 우선 사용 하고 무의식 적 인 자동 포장 을 조심해 야 합 니 다. 
 
     이상 은 생 성 대상 이 프로그램 에 불필요 한 성능 상의 위 해 를 가 져 오지 않도록 하 는 것 입 니 다.우 리 는 가능 한 한 생 성 대상 을 피해 야 합 니 다.반면 작은 대상 의 구조 기 는 적은 양의 디 스 플레이 작업 만 하기 때문에 작은 대상 의 생 성과 회수 동작 은 매우 저렴 하 다.특히 현대 의 JVM 실현 에 있어 서 는 더욱 그렇다.첨부 파일 을 만 드 는 대상 을 통 해 프로그램의 선명 성,간결 성과 기능 성 을 향상 시 키 는 것 은 좋 은 일이 다.
 
      반대로,자신의 대상 풀(Object pool)을 유지 함으로써 대상 을 만 드 는 것 을 피 하 는 것 은 좋 은 방법 이 아니다.풀 의 대상 이 매우 중량급 이 아니라면.진정 으로 대상 풀 을 정확하게 사용 하 는 전형 적 인 대상 예 는 데이터베이스 연결 풀 이다.데이터 베 이 스 를 연결 하 는 대 가 는 매우 비 싸 기 때문에 이 대상 들 을 재 활용 하 는 것 은 매우 의의 가 있다.그리고 데이터베이스 의 허 가 는 일정 수량의 연결 만 사용 할 수 있 도록 제한 할 수 있다.그러나 일반적으로 자신의 대상 지 를 유지 하 는 것 은 코드 를 어 지 럽 히 고 메모리 의 점용 을 증가 하 며 성능 을 손상 시 킬 수 있다.현대 의 JVM 은 고도 로 최 적 화 된 쓰레기 수 거 기 를 실현 하여 경량급 대상 탱크 의 성능 을 쉽게 초과 할 수 있다.

좋은 웹페이지 즐겨찾기