Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발자이야기

Java 메모리 관리 stack 과 heap 본문

JAVA

Java 메모리 관리 stack 과 heap

개발자가되고싶어 2021. 8. 5. 15:25
Java 메모리 관리

 

자바의 메모리 관리는 어떻게 이루어질까?

stack 영역과 heap 영역으로 나누어져 관리된다는 것은 들어 보셨을 수도 있습니다.

그럼 이제 어떻게 관리되는지를 한번 확인해봅시다.

Java heap Memory

자바 heap 공간은 객체를 생성할 때 사용됩니다. (new 키워드로 생성되는 모든 것이라고 생각하면 됩니다.)

Garbage Collection은 참조가 해제되거나 없는 객체를 heap 메모리에서 정리합니다.

GC가 진행되면 참조가 해제된 객체를 찾아 제거되는 것이 아닌 현재 참조된 객체 즉 사용중인 Live 객체를 찾고 나머지는 모두 쓰레기로 지정됩니다.

Java Stack Memory

자바 stack 메모리는 스레드 실행에 사용되며 heap 에 존재하는 개체들의 참조가 포함되어 있습니다.

stack 메모리는 stack의 특성에 맞게 LIFO(Last-In-First-out) 순서를 따릅니다.

메서드가 호출될 때마다 메서드의 로컬 값들의 참조를 가지기 위해 stack 메모리에 새 블록이 생성됩니다.

메서드가 종료되면 stack 메모리의 메서드 블록은 해제됩니다.

 

public static void main(String[] args) {
    String str1 = "oh";
    String str2 = new String("wow");
    Memory memory = new Memory();
    memory.method();
}

public void method() {
    int a = 1;
    String str = "ha";
}

위와 같은 경우 어떻게 stack 메모리에 참조를 할당하고 heap 메모리에 저장이 되는지 그림으로 살펴보겠습니다.

위의 상황을 살펴보기에 앞서 int, long, double, float, byte, short, boolean, char 의 원시 타입들은 heap 메모리에 할당되지 않으며 stack 메모리에 할당됩니다.

 

이제 그림과 코드의 상황을 살펴보겠습니다.

1. 프로그램이 실행되고 main 메서드를 만나게 되면 stack 영역에 main 메서드 블록이 할당됩니다.

2. str1 = "oh" 문자열이 생성되어 힙 공간 의 String pool 영역에 들어갑니다.

3. str2 = new String("wow") 생성자를 통해 생성된 str2는 String pool 영역이 아닌 따로 할당되며 stack에 참조를 가지고 있습니다.

4. memory 변수명을 가진 Memory 객체가 생성되며 heap 영역에 할당됩니다. 그리고 Memory 객체의 참조값을 가지고 stack 영역에 함께 할당됩니다.

5. memory 객체의 메서드를 호출 함 으로써 stack 영역에 새로운 method 블록이 할당됩니다.

6. memory 메서드의 내용을 위의 설명과 같이 heap 영역과 stack 영역에 할당을 하며 메서드의 마지막 종료( } ) 부분을 만나게 되면 stack 에서 블록이 해제(pop)됩니다.

 

계속해서 위와 같은 상황을 거치며 메모리에 할당과 해제가 이루어 집니다.

stack 메모리 영역은 그때그때 할당하여 사용하며 pop하여 해제합니다. 이때 heap 영역 내에 참조가 끊어진 객체들이 남게되는데 이 객체들은 GC(Garbage Collection) 가 수행될때 정리됩니다. 간단히 살펴본 바로는 GC가 수행되는 타이밍은 알 수 없으며 완전한 무작위 입니다. 그렇다고 system.gc 를 직접 호출하여 사용하지 맙시다. GC 과정은 꽤나 복잡하고 무거운 작업입니다.

GC의 자세한 메모리 해제는 추후 학습하여 포스팅 하도록 하겠습니다.

 

알수 있었던것

  • 원시타입의 데이터는 heap 영역이 아닌 stack 영역에 할당됩니다.
  • 객체가 생성되면 항상 heap 메모리 영역에 할당되고 stack 메모리 영역에 객체의 참조가 포함됩니다.
  • stack 메모리가 가득 차면 StackOverFlow 에러가 발생하며 heap 메모리가 가득 차면 OutOfMemory 에러가 발생합니다.
  • stack 메모리가 heap 메모리보다 훨씬 작습니다 그래서 작게 유지되어야 합니다. 그리고 빠릅니다. 이유는 stack 의 LIFO의 단순성과 그때그때 정리를 해주기 때문이며 heap 메모리 영역은 복잡합니다.
  • 무조건적인 전역변수의 사용은 피하고 가능하다면 지역변수를 이용합시다. 지역변수의 경우는 해당 메서드가 종료되면 GC 요건이 충족 되지만 전역변수는 더 오래 남거나 프로그램이 종료 될 때까지 남게 될 수 있습니다.

 

이상 Java의 메모리 할당에 대해 알아보았습니다. 해당 내용의 마무리를 위해서는 GC의 수행 과정을 이해하여 마무리를 해야 할 것 같습니다.

 

틀린점은 지적부탁드리며 읽어주셔서 감사합니다.

'JAVA' 카테고리의 다른 글

Java String vs StringBuffer vs StringBuilder  (0) 2021.08.12
Java interface vs abstract(추상클래스) 차이  (0) 2021.08.11
java Hashmap vs Hashtable  (0) 2021.08.03
java ArrayList, LinkedList  (0) 2021.07.30
java list vs map  (0) 2021.07.27