Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 메모리 누수(Memory Leak)란? 원인과 OutOfMemoryError 발생 예제까지 총정리

Java에서는 가비지 컬렉션(Garbage Collector)이 소멸자(Destructor) 역할을 대신하며, 사용하지 않는 객체를 자동으로 정리해 줍니다. 그렇다면 코드 어딘가에 여전히 참조가 남아 있는 객체는 어떻게 될까요?

참조가 하나라도 유지되고 있다면 해당 객체는 할당 해제(de-allocation)될 수 없고, 그 메모리도 회수되지 못합니다. 이런 상황이 반복되어 생성되거나 참조된 객체들이 실제로는 전혀 사용되지 않는 상태로 계속 쌓이게 되는데, 바로 이것이 메모리 누수(Memory Leak)입니다.


OutOfMemoryError와 프로그램 종료

메모리 누수가 누적되어 허용된 메모리 한계를 초과하면 프로그램은 오류를 던지며 강제로 종료됩니다. 이때 발생하는 대표적인 오류가 바로 java.lang.OutOfMemoryError입니다.

그렇기 때문에 Java 개발 시에는 항상 더 이상 필요하지 않은 객체에 대한 모든 참조를 제거하여, 가비지 컬렉터가 해당 객체를 자동으로 소멸시킬 수 있도록 하는 것이 권장됩니다.


메모리 부족 상황을 보여주는 예제

아래 예제는 과도한 메모리를 사용하려고 할 때 컴파일러(실행 환경)가 공간 부족으로 실패하는 과정을 보여줍니다.

예제 코드

import java.util.Vector;
public class Demo{
    public static void main(String[] args){
        Vector my_v1 = new Vector(314567);
        Vector my_v2 = new Vector(784324678);
        System.out.println("This is the last line to be printed");
    }
}

실행 결과

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.Vector.<init>(Vector.java:142)
at java.base/java.util.Vector.<init>(Vector.java:155)
at Demo.main(Demo.java:7)

예제 코드 분석

Demo라는 클래스의 main 함수 안에서 두 개의 Vector 객체가 생성되며, 각각 지나치게 큰 크기가 할당되었습니다. 마지막 print 문은 실행 흐름이 해당 라인까지 도달했는지 확인하기 위해 작성된 것입니다.

하지만 실제로는 이 라인에 도달하지 못합니다. 두 벡터가 차지하려는 공간이 너무 방대해서 힙(heap) 영역에 그만큼의 메모리를 할당할 수 없기 때문이며, 결국 OutOfMemoryError가 발생하면서 프로그램이 비정상 종료됩니다.


핵심 요약

  • 가비지 컬렉터는 참조가 없는 객체만 회수할 수 있습니다.
  • 불필요한 참조가 남아 있으면 메모리 누수가 발생합니다.
  • 누수가 누적되면 OutOfMemoryError로 프로그램이 종료됩니다.
  • 사용이 끝난 객체는 반드시 참조를 제거(null 처리 등)해 주는 것이 좋습니다.