Search
Duplicate

힙 오염(Heap Pollution)

개요

JVM의 메모리공간인 Heap Area가 오염된 상태
: 주로 매개변수화 타입의 변수가 타입이 다른 객체를 참조할 때 발생한다.

원인

원시 타입과 매개변수 타입을 동시에 사용하는 경우
확인되지 않은 형변환을 수행하는 경우
소스코드를 분리하면서 발생할 수 있다.

자세히

  제네릭 타입

우리는 제네릭을 사용하여 타입안정성을 보장받을 수 있다.
하지만, 이 기능은 컴파일을 하는 시점까지만 유효하고 그 이후로는 모두 소거된다.
그래서, 컴파일끝난 클래스 파일의 코드를 보면 타입 파라미터가 사라지고, Object를 삽입하여 하위 호환성을 해결한다. 이는 제네릭이 도입되기전 (JDK 5 이전)에 존재하던 로 타입(Law Type)과의 호환성을 위해서인데, 이런 타입 파라미터의 소거라는 특성과 컴파일러의 특성이 합쳐져서 힙 오염이 발생할 수 있다. 다음 코드는 힙 오염이 발생하는 코드로 살펴보자.
public static void main(String[] args) { List<Integer> list = (ArrayList<Integer>)Arrays.asList(1,2,3); Object obj = list; List<String> strList = (List<String>) obj; System.out.println("strList.get(1) = " + strList.get(1)); }
Java
복사
이 코드는 컴파일 당시에는 에러가 발생하지 않는다. 하지만 실제 코드를 실행시켜보면 ClassCastException이 발생하는데, 우선 타입 캐스팅 연산자는 컴파일러가 검사하지 않기 때문에 캐스팅의 가능여부를 떠나 참조변수에 저장이 가능한지만 검사한다, 그리고 컴파일 이후 타입 매개변수는 소거되기 때문에 Object타입이 되기 때문에 이 이후에는 strList.add(”abc”) 같은 코드를 작성해도 문제 없는 코드라고 판단하는 것이다. 이러한 경우를 힙 오염(heap pollution)이라 한다.

대안책

Collections 유틸리티 클래스의 checkedList 메서드를 사용하면 된다
List<Integer> integers = Collections.checkedList(new ArrayList<>(), Integer.class);
Java
복사