반응형
자바에서의 메모리 누수
자바의 메모리 누수는 더 이상 사용되지 않는 객체들이 가비지 컬렉터에 의해 회수되지 않고 누적이 되는 현상 을 의미합니다.
Old 영역에 누적된 객체로 인해서 메이저 GC가 빈번하게 발생하게 되면 프로그램의 응답속도가 늦어지다 결국 OOM(OutOfMemory)오류로 프로그램이 종려 됩니다.
가비지 컬렉션을 통해 소멸 대상이 되는 객체가 되기 위해서는 유효한 참조가 존재하지 않아야 합니다.
즉, 다 쓴 객체에 대한 참조를 해제하지 않으면 가비지 컬렉션의 대상이 되지 않아 계속 메모리가 할당 되는 메모리 누수가 발생하게 됩니다.
메모리 누수가 발생하는 원인
- static 변수가 객체를 참조하고 있는 경우
- static 변수는 프로그램 종료 시점에 메모리가 반환되고, 사용하지 않아도 메모리를 점유하고 있습니다.
그렇기 때문에 static 변수를 사용하고 있다면 정말 static 이여아만 했는지 확인해보세요
( 참고로 저는 static 변수는 재사용 목적 및 여러 컨트롤러에서 공유하는 목적으로 사용하곤 합니다. static 이외에 좋은 방법이 있다면 언제든 피드백 주세요!!)
- static 변수는 프로그램 종료 시점에 메모리가 반환되고, 사용하지 않아도 메모리를 점유하고 있습니다.
- stack 에서 Heap에 있는 객체를 참조하고 있는 경우
- 무의미한 Wrapper 객체를 생성하는 경우
- GC는 Immutable(불변의) 객체를 제거 대상에서 제외 합니다. 컨테이너 자체가 사라질 대 같이 삭제합니다. 그래서 String은 StringBuilder에 비해 Immutable 객체이기 때문에 힙에 계속 쌓여 메모리를 점유하고 있습니다. Wapper class 객체는 모두 Immutable이기 때문에 주의해서 사용해야 합니다.
- Map에 Immutable 데이터를 해제하지 않는 경우
- Map에는 강력한 참조가 있어서, 내부 객체가 사용되지 않을때도 GC 대상이 되지 않습니다. Map의 데이터의 메모리를 해제해야 합니다.
WeekHashMap 을 사용한다면 내부 데이터를 초기화 할 수 있습니다.
- Map에는 강력한 참조가 있어서, 내부 객체가 사용되지 않을때도 GC 대상이 되지 않습니다. Map의 데이터의 메모리를 해제해야 합니다.
- 스트림객체를 사용하고 닫지 않은 경우
- 아래의 코드를 보면 try 블록에서 연결 리소스를 닫는 메서드를 호출하였기 때문에 예외가 발생하는 경우 연결이 닫히지 않습니다.
따라서 연결이 풀로 다시 돌아오지 않기 때문에 메모리 누수가 발생합니다. 또한 객체를 닫지 않았기 때문에 데드락이 발생할 가능성도 높습니다.
finally 블록에 닫는 내용을 넣거나 TryWithResource를 사용해야 합니다!
- 아래의 코드를 보면 try 블록에서 연결 리소스를 닫는 메서드를 호출하였기 때문에 예외가 발생하는 경우 연결이 닫히지 않습니다.
try{
Connection conn = DriverManager.getConnection();
// 에러 발생
conn.close()
} catch(Exception e){}- 맵의 키를 사용자 객체로 정의하면서 equals(), hashcode()를 재정의 하지 않아서 같은 키로 착각하여 데이터가 계속 쌓이게 되는 경우
- 맵의 키를 사용자 객체로 정의하면서 equals(), hashcode()를 재정의 하였지만 키 값이 불변 데이터가 아니라서 데이터 비교시 계속 변하게 되는 경우
- 자료구조를 생성하여 사용하면서 , 구현 오류로 인해 메모리를 해제 하지 않은 경우
마치며
최근에 제가 구현한 코드에서 메모리 누수를 발견하였습니다. 서비스를 1회 실행 시키면 요청한 내용에 누수되는 메모리가 늘어나고 있었습니다.
이슈가 발생한 원인은 Opencv (영상을 처리하기 위함)을 사용하면서 생성한 인스턴스를 제대로 반환하지 않은 이슈 및 반환을 했음에도 불구하고 일부는 메모리 해제가 되지 않는 opencv의 고질적인 이슈였습니다. 그래서 opencv를 사용하지 않고 제가 원하는 결과를 반환 할 수 있도록 코드를 수정하여 이슈를 해결하였습니다. 덕분에 메모리 누수 및 가비지 컬렉션에 대해 공부중입니다. 다음 글에서는 가비지 컬렉션 혹은 자바의 메모리?에 대한 글을 작성해보겠습니다..!
반응형
'Dev > Java' 카테고리의 다른 글
| [Java] Default Method in Java8 (0) | 2022.11.07 |
|---|---|
| [Java] Garbage Collection(가비지 컬렉션) 톺아보기 (1) | 2022.10.02 |
| 쓰레드 동기화 (Thread Synchronization) (0) | 2022.08.06 |
| Optional의 안티 패턴을 피하는 방법 😎 (0) | 2022.07.22 |
| Optional 제대로 알고 쓰는건가요? (0) | 2022.07.10 |