Java/Java 기타

[Java] 메모리 구조와 가비지 컬렉션

excited-hyun 2021. 11. 10. 15:15
반응형

Java의 메모리 구조

가비지 컬렉션에 대해 알아보기에 앞서 java의 메모리 영역에 대해 간단하게 다뤄보겠습니다.

static / stack / heap  이렇게 세 영역으로 구분됩니다.

 

Static 영역

하나의 JAVA 파일은 크게 필드(field), 생성자(constructor), 메소드(method)로 이루어집니다.

필드에서 선언된 전역변수와 static 멤버변수가 Static 영역에 저장됩니다.

Static 영역의 데이터는 프로그램이 시작할 때부터 끝날 때까지 계속 메모리에 유지 됩니다. 그렇다보니 전역변수를 과하게 많이 사용하다 보면 메모리가 부족 문제가 발생할 수 있어 필요한 변수만 전역변수로 사용해야 합니다.

 

Stack 영역

 

 

메소드에서 정의한 기본 자료형(int, double, byte, long, boolean)에 해당되는 지역변수 또는 매개 변수가 저장되는 영역입니다. 

해당 메소드가 호출 될 때 메모리에 할당되고 실행이 끝나면 메모리에서 사라지게 됩니다.

 

Heap 영역

new를 통해 생성된 인스턴스 변수가 저장되는 영역입니다.

heap 영역에 보관되는 메모리는 stack 영역과 달리 메소드의 호출이 끝나도 사라지지 않고 유지됩니다.

가비지가 되어 가비지 컬렉션에 의해 지워지거나 JVM이 종료될 때 까지 유지 됩니다.

 

 

가비지(Garbage)란?

가비지는 더 이상 프로그램에서 사용되지 않는 메모리를 말합니다.

java에서 new를 통해서 Heap 영역의 메모리에 할당되어 사용되던 객체가 더 이상 사용되지 않게 됐을 때 가비지에 해당하게 되는 것이죠!

 

C언어를 사용할 때는 동적할당을 이용해서 생성했던 메모리를 항상 free()로 해제해 메모리 누수를 방지했던 기억이 있는데, java를 사용하면서는 new로 생성한 객체를 해제해준 적이 없는것 같습니다. 

그 이유는 java 자체에서 이러한 메모리 누수를 방지해주는 기능인 가비지 컬렉션을 가지고 있기 때문입니다.

 

가비지 컬렉션이란?

앞서 말했듯이 정리되지 않은, 유효하지 않은 메모리인 가비지를 알아서 정리해주는 기능을 합니다.

Heap 메모리의 누수를 방지하기 위해 참조되지 않는 객체들을 해제해 재활용 가능한 공간들을 만드는 작업입니다.

이 덕분에 개발자는 메모리 누수를 신경쓰지 않고 프로그램 구현에만 집중할 수 있게 됩니다.

 

가비지 컬렉션 과정

Stop-the-world

가비지 컬렉션 실행을 위해 JVM이 애플리케이션의 실행을 멈추는 것을 말합니다. 이것이 실행되면 가비지 컬렉션을 실행하는 쓰레드를 제외한 나머지 쓰레드들이 모두 작업을 멈추게 됩니다. 그런 뒤 가비지 컬렉션의 작업이 완료된 후에 중단됐던 작업들이 다시 시작됩니다.

가비지 컬렉션은 여러 알고리즘을 사용하는 방식들이 있는데 어떤 알고리즘을 사용하더라도 stop-the-world는 반드시 발생하게 됩니다.

 

가비지 컬렉션의 역할

  1. 메모리 할당
  2. 사용 중인 메모리 인식
  3. 사용하지 않는 메모리 인식

 

JVM Heap

크게 보면 JVM heap 메모리는 이렇게 young과 old로 나눠져 있습니다.

 

Young 영역 (Minor GC)

이곳은 새로운 객체가 생성되는 곳입니다. 이 영역이 가득차면 가비지 컬렉션(이때는 Minor GC)이 동작하게 되는 것입니다.

이 young 영역은 또 eden, S0, S1 이렇게 3 영역으로 나눠집니다.

 

최근에 만들어진 객체는 eden 영역에 위치하게 됩니다. eden 영역이 꽉 차게 되면 Minor GC 가 동작하고 이때 살아남는 객체들이 survivor 영역(S0, S1)으로 이동합니다.

또한 Minor GC는 survivor 영역도 같이 검사하여 다른 survivor 역역으로 이동시킵니다. 즉 두 survivor 영역중 하나는 반드시 비어있습니다.

여러번에 Minor GC를 거치면서  young 영역이 가득차게 되면 여전히 살아있는 객체들은 old 영역으로 이동됩니다.

 

Old 영역 (Major GC)

Old 영역에는 Minor GC에서 살아남은 객체들이 있습니다. Old 영역에서 메모리가 가득차게되면 Major GC가 발생하게 됩니다.

Minor GC의 경우엔 객체의 수명이 짧고 많은 객체를 검사하지 않기 때문에 빠른 속도로 이루어져 애플리케이션에 영향을 거의 주지 않지만 Major GC의 경우엔 old에 있는 수명이 긴 모든 객체들을 검사해야 하기 때문에 상대적으로 긴 시간이 요구됩니다.따라서 이 때 stop-the-world 가 일어나는 것인데요. 만약 애플리케이션의 Major GC가 자주 일어난다면 그만 큼 자주 애플리케이션이 동작을 못하게 되는 것이기 때문에 이 횟수를 최소화하는 것이 좋습니다.따라서 GC를 모니터링하여 발생 횟수 감소를 위한 튜닝을 하는 것도 중요합니다.

 

728x90
반응형