equals()와 hashCode() 구현 오류로 인한 Java 메모리 누수 문제
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
개발 툴
대상자
- Java 개발자 (특히 컬렉션 및 커스텀 객체 사용자)
- 중간 수준 (오브젝트 동등성, 해시 기반 컬렉션 이해 필요)
핵심 요약
equals()
와hashCode()
오버라이딩 누락 → HashMap/HashSet에서 객체 중복 인식 → 메모리 누수 발생equals()
/hashCode()
는 항상 함께 오버라이딩 해야 하며,Objects.equals()
및Objects.hash()
사용 권장- Lombok의
@EqualsAndHashCode
애너테이션 활용으로 구현 간소화 가능
섹션별 세부 요약
1. 메모리 누수의 주요 원인
equals()
/hashCode()
누락 → Java의 기본 동등성 비교(참조 동일성)로 인해 동일한 값의 객체를 중복으로 인식HashMap
/HashSet
은equals()
/hashCode()
기반으로 중복 제거 및 키 관리 → 오류 시 컬렉션 무한 성장remove(obj)
메서드는equals()
의존 → 오류 시 객체 제거 불가
2. 실무 예시: 캐시 시스템
User
객체의equals()
/hashCode()
오류 →computeIfAbsent()
로 인해 동일 사용자에 대한 캐시 무한 증가Map
에서 동일한 사용자 인식 불가 → 메모리 누수 발생
3. 정확한 구현 방법
equals()
오버라이딩:Objects.equals()
로 필드 비교hashCode()
오버라이딩:Objects.hash()
로 필드 해시 계산- Lombok 활용:
@EqualsAndHashCode
애너테이션으로 자동 생성
4. 테스트 및 검증
- 단순 콘텐츠 테스트보다 Map/Set 동작 테스트 필수
equals()
/hashCode()
구현 오류는 단위 테스트로 발견 어려움
결론
- 모든 커스텀 객체에서
equals()
와hashCode()
는 반드시 함께 오버라이딩 - Lombok의
@EqualsAndHashCode
사용으로 구현 간소화 - Map/Set 기반 로직은 반드시
equals()
/hashCode()
테스트 포함