반응형
리눅스 메모리 누수에 대해 알아보겠습니다.
메모리 누수란 ?
프로세스 메모리 사용량이 지속적으로 증가하는 것을 메모리 누수라고 합니다.
그 원인은 대체로 프로그램이 더 이상 필요하지 않은 메모리를 해제하지 않아 사용 가능한 메모리가 점점 줄어 드는 현상 입니다.
메모리 누수가 발생하며 물리적인 메모리 부족으로 스와핑이 일어나고 급격한 성능저하를 유발할 가능성이 높습니다.
메모리 누수 조사는 인내와 체계적인 접근이 필요한 작업입니다.
한 번에 모든 원인을 찾기보다는 점진적으로 문제를 좁혀나가는 접근법이 효과적입니다.
- 증상 확인: 메모리 사용 패턴이 정말 누수인지 확인합니다. 단순히 높은 메모리 사용량이 꼭 누수를 의미하지는 않습니다.
- 간단한 모니터링으로 시작: jstat, top, ps 등의 기본 도구로 전반적인 메모리 사용 패턴을 확인합니다.
- GC 로그 활성화 및 분석: GC 패턴을 통해 Old Generation 메모리의 증가 여부를 확인합니다.
- 힙 덤프 분석: 메모리 누수가 의심된다면 여러 시점에서 힙 덤프를 생성하여 비교 분석합니다.
- 코드 검토: 분석 결과를 바탕으로 관련 코드를 검토하고 수정합니다.
누수 증상 확인을 위한 도구
1. tcmalloc
-> C, C++ 애플리케이션에서 메모리 누수를 감지하는 데 사용합니다.
2. jmap, MAT, Jprofiler
-> Java는 메모래ㅣ 관리가 JVM 내부에서 이루어지기 때문에 JVM 특화 도구가 적합합니다.
메모리 단편화란 ?
메모리 단편화는 컴퓨터 시스템에서 사용 가능한 메모리가 작은 조각으로 나뉘어져 있어 전체 가용 메모리는 충분하지만 연속된 큰 메모리 블록이 필요할 때 할당할 수 없게 되는 현상 입니다.
메모리 누수가 단편화에 미치는 영향
메모리 누수는 여러 가지 방식으로 메모리 단편화를 악화시킬 수 있습니다:
- 할당 패턴 변화: 메모리 누수가 발생하면 사용 가능한 메모리가 줄어들면서 시스템은 남은 공간에서 객체를 할당해야 합니다. 이로 인해 비효율적인 할당 패턴이 생길 수 있고, 결과적으로 단편화가 심해집니다.
- GC 활동 증가: Java와 같은 가비지 컬렉션 환경에서 메모리 누수는 GC 활동을 증가시킵니다. GC가 자주 발생하면 객체가 생성되고 제거되는 과정에서 단편화가 발생할 가능성이 높아집니다.
- 큰 객체의 생존: 메모리 누수로 인해 큰 객체들이 오래 살아남게 되면, 이들 주변의 메모리 공간이 단편화될 가능성이 높아집니다. 예를 들어, 여러 큰 객체들 사이에 작은 공간들이 생기고, 이 공간들은 새로운 큰 객체를 할당하기에는 너무 작을 수 있습니다.
- 힙 압박: 메모리 누수로 인해 힙이 계속 증가하면 결국 시스템은 Full GC를 수행해야 하는데, 이 과정에서 압축(compaction)이 제대로 이루어지지 않으면 단편화가 악화될 수 있습니다.
Spring 애플리케이션 메모리 누수와 단편화
- 장기 실행 캐시: 제대로 관리되지 않는 캐시는 메모리 누수의 주요 원인이 될 수 있습니다. 이러한 캐시에 다양한 크기의 객체가 저장되고 일부만 제거되면, 남은 공간은 단편화됩니다.
// 문제가 될 수 있는 캐시 구현
public class ProblemCache {
private static final Map<String, Object> cache = new HashMap<>();
// 캐시 항목이 절대 제거되지 않음
public static void put(String key, Object value) {
cache.put(key, value);
}
}
- 스트림 처리 오류: 파일이나 네트워크 스트림을 적절히 닫지 않으면 메모리 누수가 발생할 수 있으며, 이는 힙 공간의 비효율적 사용으로 이어져 단편화를 촉진합니다.
- 싱글톤 빈의 컬렉션 필드: 싱글톤 빈에 컬렉션 필드가 있고 여기에 계속 항목이 추가만 되면 메모리 누수가 발생합니다. 이러한 컬렉션이 다양한 크기의 객체를 담고 있다면 이후 메모리 할당 패턴에 영향을 미쳐 단편화를 악화시킬 수 있습니다.
- 커넥션 풀 관리 실패: 데이터베이스 연결과 같은 리소스가 제대로 반환되지 않으면 메모리 누수가 발생합니다. 이러한 리소스는 종종 큰 메모리 공간을 차지하며, 해제되지 않는 연결 주변에 단편화된 공간이 생길 수 있습니다.