Java 가비지 컬렉션이란 무엇인가요?

성층권 구름 속 상하이 루자쭈이의 조감도

Java 가비지 컬렉션이란 무엇인가요?

가비지 컬렉션은 에덴 스페이스에서 생성된 객체에 대한 메모리 할당 및 할당 해제를 자동으로 관리하는 Java 프로그래밍 언어의 핵심 기능입니다.

Java의 가비지 컬렉션을 사용하면 개발자가 메모리 관리에 신경 쓸 필요 없이 코드 작성에만 집중할 수 있으므로 복잡하고 대규모 애플리케이션을 구축하는 데 Java가 널리 사용됩니다. 그러나 Java 개발자가 코드의 성능을 최적화하고 일반적인 메모리 관련 오류를 방지하려면 가비지 컬렉션이 어떻게 작동하는지 반드시 이해해야 합니다.

이 가이드에서는 Java 컬렉션의 이점, 다양한 유형의 컬렉터, 코딩할 때 따라야 할 모범 사례 등 가비지 컬렉션의 기본 사항을 살펴봅니다. 이제 가비지 컬렉션이 어떻게 작동하는지 자세히 알아보겠습니다.

전문가의 인사이트를 바탕으로 한 최신 기술 뉴스

Think 뉴스레터를 통해 AI, 자동화, 데이터 등 가장 중요하고 흥미로운 업계 동향에 대한 최신 소식을 받아보세요. IBM 개인정보 보호정책을 참조하세요.

감사합니다! 구독이 완료되었습니다.

구독한 뉴스레터는 영어로 제공됩니다. 모든 뉴스레터에는 구독 취소 링크가 있습니다. 여기에서 구독을 관리하거나 취소할 수 있습니다. 자세한 정보는 IBM 개인정보 보호정책을 참조하세요.

OutofMemoryErrors란 무엇인가요?

OutofMemoryError는 프로그램이나 애플리케이션이 사용 가능한 양보다 많은 메모리를 할당하려고 할 때 발생하는 오류 유형입니다. 이 오류는 애플리케이션을 실행하는 동안 Java Virtual Machines(JVM) 또는 다른 플랫폼의 메모리가 부족할 때 발생합니다.

일반적으로 애플리케이션이나 프로그램이 새 객체를 생성하려고 하지만 JVM이 이를 수용할 만한 메모리를 할당할 수 없을 때 OutofMemoryError가 발생합니다. 이 오류는 애플리케이션이 메모리를 너무 많이 사용하고 있으며 메모리를 제대로 해제하지 못하는 경우에도 발생할 수 있습니다.

OutofMemoryError가 발생하면 보통 애플리케이션이 충돌하고 종료됩니다. 이 오류는 이미지 또는 동영상 처리 애플리케이션과 같이 많은 양의 메타데이터를 처리하는 프로그램 또는 대용량 데이터베이스를 처리하는 프로그램에서 흔히 발생합니다.

이 오류를 해결하려면 애플리케이션에서 사용할 수 있는 메모리 양을 늘리거나 애플리케이션의 메모리 사용량을 최적화해야 할 수 있습니다. 이 작업은 JVM 매개변수를 수정하거나 메모리 프로파일러 도구를 사용하여 메모리 누수 또는 비효율적인 메모리 사용을 식별하여 수행할 수 있습니다.

애플리케이션 개발

시작하기: 클라우드에서 기업용 애플리케이션 개발

이 영상에서 Peter Haumer 박사는 IBM Z Open Editor, IBM Wazi 및 Zowe 등 다양한 구성 요소와 사례를 시연하며 오늘날 하이브리드 클라우드에서의 최신 기업용 애플리케이션 개발이 어떤 모습인지 설명합니다. 

Java 가비지 컬렉션은 어떻게 작동하나요?

Java에서 모든 객체는 객체의 동적 할당을 위해 예약된 메모리의 일부인 힙에 저장됩니다. 객체가 더 이상 프로그램의 어떤 부분에서도 참조되지 않으면 가비지 컬렉션 대상이 됩니다.

Java의 가비지 컬렉터는 주기적으로 힙 메모리를 스캔하여 사용되지 않는 객체를 찾습니다. 가비지 컬렉션 과정에는 표시, 청소, 압축 등 여러 단계가 포함됩니다.

  • 표시 - 가비지 컬렉션의 첫 번째 단계는 프로그램에서 아직 참조하고 있는 모든 객체를 표시하는 작업입니다. 전역 변수, 로컬 변수 및 메서드 매개변수와 같은 루트 객체 집합에서 시작해 해당 루트에서 연결할 수 있는 모든 객체를 추적해 이 작업을 수행합니다. 루트에서 접근할 수 없는 객체는 가비지 컬렉션 대상으로 간주됩니다.

  • 청소 - 표시 단계가 끝나면 가비지 컬렉터가 Java 힙을 청소하여 더 이상 참조되지 않는 객체에서 사용하는 메모리를 식별하고 회수합니다. 참조되지 않는 객체에서 사용하는 메모리를 할당 해제하고 이 메모리를 사용 가능한 메모리 풀에 다시 추가하는 작업도 이 단계에 포함됩니다.

  • 압축 - 일부 가비지 컬렉션 알고리즘에서는 청소 단계 다음에 압축 단계가 이어지는데, 이 단계에서는 나머지 객체에서 사용하는 메모리를 재배열하여 조각화를 최소화합니다. 객체를 서로 더 가깝게 이동시키고 더 큰 연속 메모리 블록을 만드는 작업이 수행됩니다.

Java Virtual Machines(JVM)는 자동으로 가비지 컬렉션을 수행하므로 프로그래머가 메모리를 수동으로 관리할 필요가 없습니다. 가비지 컬렉터는 별도의 스레드에서 실행되며 일반적으로 백그라운드에서 작동하므로 프로그램의 정상적인 실행에 영향을 미치지 않습니다.

Java 가비지 컬렉터 유형

Java 가비지 컬렉션 알고리즘에는 전체 가비지 컬렉션과 증분 가비지 컬렉션이라는 두 가지 주요 유형이 있습니다.

전체 또는 주요 가비지 컬렉션

전체 가비지 컬렉션은 프로그래밍 언어 런타임 시스템의 일부인 가비지 컬렉터가 프로그램에서 사용하는 모든 메모리를 검색하고 프로그램에서 더 이상 사용하지 않는 객체를 컴파일하는 프로세스입니다. 그 후 해당 객체는 가비지로 표시되어 메모리에서 제거할 수 있습니다.

전체 가비지 컬렉션은 일반적으로 Java 또는 Python과 같이 자동 메모리 관리를 사용하는 프로그래밍 언어의 런타임 시스템에서 수행됩니다. 이 과정에서 가비지 컬렉터는 가비지 객체 검색을 수행하기 위해 프로그램 실행을 일시 중지하므로 프로그램 성능이 일시적으로 느려질 수 있습니다.

전체 가비지 컬렉션은 일반적으로 프로그램에서 사용하는 메모리 양이 특정 임계값에 도달하거나 프로그램에서 새 메모리 블록을 요청했는데 사용 가능한 메모리가 충분하지 않을 때 트리거됩니다. 전체 가비지 컬렉션의 목표는 프로그램에 필요하지 않은 메모리를 회수하여 프로그램의 다른 부분이나 동일한 시스템에서 실행되는 다른 프로그램에서 사용할 수 있게 만드는 것입니다.

증분형 또는 사소한 가비지 컬렉션

증분형 가비지 컬렉션은 프로그래밍 언어 및 런타임 환경에서 프로그램에 더 이상 필요하지 않은 메모리를 자동으로 회수하는 데 사용되는 메모리 관리 기술의 한 유형입니다. 메모리에서 사용되지 않는 객체를 식별하고, 해당 객체가 점유하는 메모리를 프로그램의 다른 부분에서 재사용할 수 있도록 할당 해제합니다.

증분형 가비지 컬렉션에서는 가비지 컬렉터가 주기적으로 프로그램 메모리를 스캔하여 나 세대의 힙 메모리에서 도달할 수 없는 객체를 찾습니다. 가비지 컬렉터는 이 스캔 프로세스 중에 프로그램 실행을 중지하는 대신, 스캔 프로세스를 '증분'이라는 관리하기 쉬운 작은 조각으로 나눕니다. 가비지 컬렉터는 각 단계에서 프로그램 메모리의 일부를 스캔하여 필요하지 않은 객체를 식별하고 다시 사용할 수 있는 것으로 표시합니다.

증분을 사용하면 가비지 컬렉터가 오랜 기간 동안 프로그램 실행을 중단하지 않고 메모리를 작은 덩어리로 회수할 수 있습니다. 이렇게 하면 프로그램이 응답성을 유지하면서 가비지 컬렉션 프로세스로 인해 심각한 일시 중지나 지연이 발생하지 않습니다.

그러나 증분형 가비지 컬렉션은 프로그램 메모리를 더 자주 스캔하기 때문에 표시 및 청소 또는 세대별 가비지 컬렉션과 같은 다른 유형의 가비지 컬렉션 기술보다 효율성이 떨어질 수 있습니다. 또한, 가비지 컬렉터가 각 증분 사이에 상태 정보를 유지해야 하므로 증분을 사용하면 프로그램 실행에 일부 오버헤드가 발생할 수 있습니다.

Java 가비지 컬렉션의 이점

전반적으로 Java의 가비지 컬렉션은 개발자에게 유용한 많은 이점을 제공합니다. Java의 가비지 컬렉션으로 얻을 수 있는 몇 가지 이점은 다음과 같습니다.

  1. 수동 메모리 관리 불필요
  2. 메모리 누수 방지
  3. 동적 메모리 할당
  4. 성능 향상
  5. 메모리 최적화
  • 수동 메모리 관리 불필요: 가비지 컬렉션을 사용하면 개발자가 메모리 할당 및 할당 해제를 수동으로 관리할 필요가 없습니다. 즉, 프로그래머가 메모리 관리에 신경 쓰지 않고 코드 작성에 더 집중할 수 있어 오류를 줄이고 생산성을 향상할 수 있습니다.

  • 메모리 누수 방지: 가비지 컬렉션은 프로그램이 필요하지 않은 메모리를 해제하지 않아서 발생할 수 있는 메모리 누수를 방지하는 데 도움이 됩니다. 프로그램이 메모리를 해제하지 않으면 필요한 것보다 더 많은 메모리를 소비해 성능이 저하되고, 결국 충돌이 발생할 수 있습니다.

  • 동적 메모리 할당: Java 가비지 컬렉션은 동적 메모리 할당을 지원하므로 필요에 따라 런타임에 메모리를 할당할 수 있습니다. 이렇게 하면 메모리 할당 오류를 방지하고 프로그램의 효율성을 높일 수 있습니다.

  • 성능 향상: 가비지 컬렉션은 메모리 관리에 소요되는 시간을 줄여 프로그램의 성능을 개선하는 데 도움이 될 수 있습니다. 덕분에 실행 시간이 단축되고 프로그램 응답성이 향상될 수 있습니다.

  • 메모리 최적화: 가비지 컬렉션은 프로그램의 한 부분에서 사용하지 않는 메모리를 프로그램의 다른 부분에 재사용하여 메모리 사용을 최적화합니다. 이는 메모리 사용량을 줄이고 전반적인 프로그램 효율성을 개선하는 데 도움이 될 수 있습니다.

메모리를 자동으로 관리하고, 메모리 누수를 방지하고, 동적 메모리 할당을 활성화하고, 성능을 개선하고, 메모리 사용을 최적화하는 Java 가비지 컬렉션 기능을 통해 개발자는 더 우수하고 효율적인 프로그램을 작성하는 데 집중할 수 있습니다.

Java 가비지 컬렉션은 어떤 이벤트로 트리거되나요?

힙이 가득 차거나 일정 시간이 지나면 Java Virtual Machines(JVM)이 가비지 컬렌션을 자동으로 트리거합니다.

Java에서 가비지 컬렉션을 트리거할 수 있는 이벤트는 여러 가지가 있습니다.

  • 힙 공간 할당: 새 객체에 메모리를 할당해야 하는데 힙에 충분한 공간이 없으면 JVM이 가비지 컬렉션을 트리거하여 사용하지 않는 메모리를 회수하거나 서바이버 공간에 저장합니다.

  • System.gc() 메소드 호출: System.gc() 메서드를 호출하여 가비지 컬렉션을 명시적으로 요청할 수 있지만, 반드시 실행된다는 보장은 없습니다.

  • 이전 세대 임계값: 가비지 컬렉션은 이전 세대 힙 공간(수명이 긴 객체를 저장하는 힙 공간)의 힙 크기가 특정 임계값에 도달했을 때 트리거될 수도 있습니다.

  • PermGen/메타스페이스 임계값: Java 8 이전의 Java 버전에서는 PermGen(영구 세대) 또는 메타스페이스(Java 8 이상) 메모리 영역의 크기가 특정 임계값에 도달하면 가비지 컬렉션이 트리거될 수 있습니다.

  • 시간 기반: 시간 간격에 따라 가비지 컬렉션이 트리거되는 경우도 있습니다. 예를 들어, JVM은 메모리 사용량과 관계없이 매시간 또는 매일 가비지 컬렉션을 트리거할 수 있습니다.

Java에서 가비지 컬렉션의 정확한 동작은 JVM 구현 및 구성에 따라 달라질 수 있다는 점에 유의하시기 바랍니다.

JVM에 가비지 컬렉터 실행을 요청하는 방법

가비지 컬렉터를 실행하도록 Java Virtual Machine(JVM)에 요청하려면 다음 단계를 따르세요.

  1. System.gc() 메서드 호출: JVM에 가비지 컬렉터를 실행하도록 요청하는 데 사용되는 메서드입니다. 이 메서드가 호출된 후 가비지 컬렉터가 즉시 실행된다는 보장은 없습니다.

  2. Runtime.getRuntime().gc() 메서드 사용: 이 메서드는 System.gc() 메서드와 유사하지만, JVM 구현에 의해 재정의될 가능성이 적습니다.
  3. -XX:+DisableExplicitGC JVM 플래그 사용: 이 플래그는 명시적 가비지 컬렉션 요청을 비활성화합니다. 즉, System.gc() 또는 Runtime.getRuntime().gc()를 호출해도 가비지 컬렉터가 트리거되지 않습니다.

JVM은 메모리 할당 및 가비지 컬렉션을 자동으로 관리하도록 설계되었으므로 가비지 컬렉터를 실행하도록 명시적으로 요청하는 것은 일반적으로 권장되지 않습니다. 명시적인 가비지 컬렉션 요청은 성능에 부정적인 영향을 미칠 수 있습니다.

객체가 가비지 컬렉션 대상이 되는 경우는 언제인가요?

프로그래밍 언어의 객체가 프로그램의 어느 부분에서도 참조되지 않을 때 가비지 컬렉션 대상이 됩니다. 자동 가비지 컬렉션은 프로그래밍 언어 런타임 환경에서 메모리를 회수하기 위해 수행되는 프로세스입니다.

대부분의 최신 프로그래밍 언어에서 가비지 컬렉션은 런타임 환경에 의해 자동으로 수행됩니다. 가비지 컬렉션에 사용되는 특정 알고리즘은 프로그래밍 언어 및 구현에 따라 다를 수 있지만, 일반적인 원칙은 동일합니다. 런타임 환경은 동적으로 할당된 객체에 사용되는 메모리 부분인 힙을 주기적으로 스캔하여 프로그램의 어느 라이브 객체에서도 더 이상 도달할 수 없는 객체를 식별합니다. 도달할 수 없는 것으로 식별된 객체는 가비지로 표시되고, 해당 메모리를 회수할 수 있습니다.

객체가 가비지 컬렉션의 대상이 되는 정확한 타이밍은 런타임 환경에서 사용하는 특정 가비지 컬렉션 알고리즘에 따라 달라집니다. 일부 알고리즘은 다른 알고리즘보다 더 공격적이며 메모리를 더 빨리 회수하는 반면, 다른 알고리즘은 성능을 최적화하기 위해 가비지 컬렉션을 지연시킬 수 있습니다. 그러나 일반적으로 런타임 환경이 자동으로 메모리를 관리하므로 프로그래머가 수동으로 메모리를 관리할 필요가 없습니다.

Java에서 사용 가능한 가비지 컬렉터는 어떤 것이 있나요?

Java 가비지 컬렉터에는 다음과 같은 여러 종류가 있습니다.

  1. 직렬 가비지 콜렉터
  2. 병렬 가비지 콜렉터
  3. 동시 마크 스윕(CMS) 컬렉터
  4. G1 가비지 컬렉터
  • 직렬 가비지 컬렉터: 직렬 가비지 컬렉터는 Java의 기본 가비지 컬렉터로, 일반적으로 처리량이 많지 않은 중소규모 애플리케이션에 사용됩니다. 이러한 유형의 컬렉터는 일반적인 '완전 멈춤' 이벤트가 발생하는 것을 방지하는 데 도움이 됩니다.

  • 병렬 가비지 컬렉터: 병렬 컬렉터는 처리량이 많은 애플리케이션을 위해 설계되었으며, 여러 CPU를 사용해 프로세스 속도를 높이기 때문에 대용량 힙이 필요한 애플리케이션에 특히 유용합니다. 이 유형의 컬렉터는 가비지 컬렉터를 실행할 때 애플리케이션 스레드를 정지시킨다는 점에 유의해야 합니다.

  • 동시 마크 스윕(CMS) 컬렉터: CMS 컬렉터는 짧은 일시 중지 시간이 필요한 애플리케이션을 위해 설계되었으며 라이브 객체가 많은 애플리케이션에 유용합니다.

  • G1 가비지 컬렉터: 대규모 힙을 위해 설계된 G1 컬렉터는 수명이 짧은 객체와 수명이 긴 객체를 혼합하여 처리할 수 있습니다. 여러 스레드를 사용하여 힙을 동시에 스캔하고 압축합니다.

각 가비지 콜렉터는 고유한 장점과 단점을 가지고 있으며, 애플리케이션의 특정 요구 사항에 따라 어떤 컬렉터를 사용할지 결정해야 합니다. 특정 애플리케이션의 성능을 최적화하기 위해 가비지 컬렉터 설정을 구성하고 조정할 수도 있습니다.

가비지 컬렉션과 메모리 누수의 차이점은 무엇인가요?

가비지 컬렉션과 메모리 누수는 모두 컴퓨터 프로그램의 메모리 관리와 관련이 있지만, 그 의미와 함의는 다릅니다.

앞서 설명한 것처럼 가비지 컬렉션은 일반적으로 프로그래밍 언어 또는 런타임 환경에서 수행되며, 프로그램이 필요 이상의 메모리를 소비하지 않도록 도와줍니다. 가비지 컬렉션은 프로그램의 다른 부분 또는 컴퓨터에서 실행 중인 다른 프로그램에서 사용되지 않는 메모리를 식별합니다.

반면에 메모리 누수는 할당된 메모리가 더 이상 필요하지 않은 경우에도 프로그램이 할당된 메모리를 해제하지 못할 때 발생합니다. 결과적으로 시간이 지날수록 프로그램이 메모리를 계속 소비하여 결국 사용 가능한 메모리가 고갈되고 프로그램 또는 전체 운영 체제가 충돌할 수 있습니다. 메모리 누수는 일반적으로 프로그램의 버그로 인해 발생하며, 식별하고 수정하기가 어려울 수 있습니다.

요약하면 가비지 컬렉션은 더 이상 필요하지 않은 메모리를 자동으로 확보하는 프로세스입니다. 메모리 누수는 메모리가 할당되었지만 프로그램에 의해 해제되지 않아 메모리 사용량이 점진적으로 누적될 때 발생합니다.

Instana를 통한 Java 애플리케이션 성능 모니터링

결론적으로 가비지 컬렉션은 사용되지 않는 메모리를 회수하여 효율적인 메모리 관리를 보장하는 Java 프로그래밍의 필수 요소입니다. Instana 관측 가능성은 개발자에게 가비지 수집 프로세스를 실시간으로 모니터링하고 최적화할 수 있는 강력한 도구를 제공합니다.

개발자는 Instana를 사용해 메모리 누수를 빠르게 식별하고, 가비지 컬렉션 설정을 최적화하고, 가비지 컬렉션과 관련된 성능 문제를 해결할 수 있습니다.

Instana의 포괄적인 모니터링 기능은 개발자에게 Java 애플리케이션의 메모리 사용량 및 가비지 컬렉션 동작에 대한 심층적인 인사이트를 제공하므로 개발자가 신뢰할 수 있는 고성능 소프트웨어를 제작할 수 있습니다. 

이 가이드에 설명된 모범 사례를 따르면 개발자가 Instana를 사용해 가비지 컬렉션 프로세스를 최적화하고 Java 애플리케이션의 전반적인 성능을 개선할 수 있습니다. Instana 관측 가능성을 통해 발생할 수 있는 모든 문제를 미리 파악하여 애플리케이션이 항상 최상의 성능을 발휘하도록 보장할 수 있습니다.

관련 솔루션
AI 기반 애플리케이션 개발

Watsonx.ai는 애플리케이션 개발 팀이 워크플로에 AI를 원활하게 통합할 수 있도록 지원합니다. 이 포괄적인 툴킷은 모델 생성에서 배포에 이르기까지 전체 AI 라이프사이클를 지원합니다.

watsonx.ai 살펴보기
IBM Z Development and Test Environment

x86 하드웨어에서 메인프레임 애플리케이션 개발, 테스트, 데모, 교육을 위한 플랫폼을 사용합니다.

Z 개발 환경 살펴보기
모바일 클라우드 컴퓨팅 솔루션

앱을 신속하게 설계하고 프로토타입을 제작하여 시장에 쉽게 출시할 수 있는 IBM의 모바일 앱 개발 플랫폼에 대해 알아보세요.

모바일 클라우드 살펴보기
다음 단계 안내

IBM Cloud Application Development Consulting Services는 클라우드 전략을 간소화하기 위한 전문가 지침과 혁신적인 솔루션을 제공합니다. IBM의 클라우드 및 개발 전문가와 협력해 애플리케이션을 현대화, 확장, 가속화하여 비즈니스에 혁신적인 결과를 제공하세요.

애플리케이션 개발 서비스 살펴보기 무료로 IBM Cloud에서 구축 시작하기