자바 프로그래밍을 하다 보면 한 번쯤은 "메모리 누수"라는 문제를 들어본 적이 있을 거예요. 그렇다면 메모리 누수가 실제로 어떻게 발생할까요? 자바는 가비지 컬렉터(Garbage Collector, GC)를 통해 사용하지 않는 객체를 자동으로 수거하는데, 그렇다면 왜 우리는 여전히 메모리 누수를 걱정해야 할까요?? 🤔
가비지 컬렉터가 잘못된 객체를 수거하지 못하게 만드는 주된 이유 중 하나는 바로 다 쓴 객체에 대한 참조를 해제하지 않기 때문이에요. 이 문제는 특히 메모리를 장시간 사용하거나, 많은 객체를 다루는 애플리케이션에서 더 심각하게 드러난다고 합니다. 가령, 우리가 다 쓴 객체를 필요 이상으로 참조하고 있는 경우, 해당 객체는 가비지 컬렉터의 대상이 되지 않으며, 그 결과 메모리가 불필요하게 사용됩니다.
import org.springframework.stereotype.Component;
@Component
public class UserContext {
private static final ThreadLocal<String> userThreadLocal = new ThreadLocal<>();
public void setUser(String user) {
userThreadLocal.set(user);
}
public String getUser() {
return userThreadLocal.get();
}
public void clear() {
userThreadLocal.remove(); // 다 쓴 객체 참조 해제
}
}
위 코드에서는 clear() 메서드를 호출하지 않으면, ThreadLocal에 저장된 값이 계속 메모리에 남아 있을 수 있어요. 이는 특히 스레드 풀을 사용하는 환경에서는 심각한 문제가 되겠죠. 스레드가 재사용되면서 이전에 저장된 값이 남아 있게 되고, 이로 인해 메모리 누수가 생길 수 있습니다. 🫠🫠
그러면 메모리 누수가 발생하면 어떤 일이 벌어질까요?
메모리 누수는 시간이 지남에 따라 애플리케이션의 메모리 사용량을 증가시키고, 결국 OutOfMemoryError를 초래할 수 있어요. 이런 문제는 장시간 실행되는 서버 애플리케이션에서 특히 치명적이며, 실제로 많은 개발자들이 메모리 누수 문제를 겪으며 애플리케이션 성능이 저하되는 현상을 경험하게 되는데 더 자세한 것은 다음 링크를 보면서 확인할 수 있어요.
그렇다면 이러한 문제를 어떻게 해결할 수 있을까요? 🤔
가장 간단한 방법은 다 쓴 객체의 참조를 null로 명시적으로 해제하는 것이에요.
이렇게 객체를 null로 설정하여, 참조를 해제를 하게 되면 해당 객체가 가비지 컬렉션의 대상이 되어 메모리가 올바르게 해제될 수 있어요. 그러나 여기서 중요한 점은 모든 객체 참조를 null로 설정하는 것은 좋은 습관이 아니며, 필요한 경우에만 사용해야 한다는 것이에요!
예를 들어, 사용된 객체가 더 이상 필요하지 않다는 것이 명확한 경우에만 참조를 null로 설정하는 것이 좋습니다.
그러면 객체를 언제 null로 참조를 해제해야 할까요?
먼저 직접 관리하는 메모리 구조에서, 예를 들어 배열과 같은 자료 구조를 사용할 때 필요해요. 두 번째는 오랜 시간 동안 유지되면서 많은 객체를 참조하는 경우, 참조 해제를 통해 메모리 사용을 줄일 수 있어요.
이 두 가지에 해당하지 않은 경우는 가비지 컬렉션이 대부분의 메모리 관리를 알아서 처리해 주기 때문에 굳이 null로 참조를 설정하지 않아도 괜찮습니다. 점점 자바 버전 업이 되면서 메모리 관리를 더 잘 수행하도록 개선된 GC 알고리즘을 사용하고 있어요. 자바 21 버전에서는 새롭게 도입한 ZGC를 통해서 메모리 자원을 효율적으로 관리하고 있어요. 처리량이 이전 버전보다 10% 개선되었다고 하는데 자세한 부분은 아래 링크롤 통해서 읽어보세요 😊
'Language > JAVA' 카테고리의 다른 글
[이펙티브 자바][아이템 9] try-finally 보다 try-with-resources 를 사용하라 - 컴도리돌이 (1) | 2024.09.27 |
---|---|
[이펙티브 자바][아이템 8] finalizer와 cleaner 사용을 피하라 - 컴도리돌이 (0) | 2024.09.11 |
[이팩티브 자바][아이템 6] 불필요한 객체 생성을 피하라 - 컴도리돌이 (4) | 2024.08.31 |
[이펙티브 자바][아이템 5] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 - 컴도리돌이 (0) | 2024.08.26 |
[이펙티브 자바][아이템 4] 인스턴스화를 막으려거든 private 생성자를 사용하라 - 컴도리돌이 (0) | 2024.08.25 |