OOP & JAVA

Java 메모리 관리

쉽코기 2021. 9. 12. 16:55

개요

  • 자바의 메모리 영역에 대해 알아본다
  • 실제 코드들을 통해 어떤 메모리에 올라갈지를 생각해본다.

 

우리가 짠 코드들이 실제로 java 안에서 어떻게 동작하고 어떤 메모리 공간에 저장되는지 정리해보려고 합니다.

자바는 .java 파일이 컴파일 되어 .class 파일이라는 바이트 코드를 생성하고 이 파일을 JVM 이 구동 시킵니다. 컴파일과 JVM의 거시적인 역할에 대한 부분도 다음에 정리해보겠습니다 . 

 

 

오늘은 오직 JVM  그중에서도  내 코드의 데이터들이 어디에 저장되는지 집중하고자  stack 과 heap에 집중해서 공부해보겠습니다 . 

 

 

 

 

 

Static area ( == Method area)

  •  .class 파일의 바이트 코드가 로드되는 곳
  • 클래스정보(멤버변수의 이름), 변수정보(데이터타입, 접근제어자정보), 메소드정보(메소드 이름, 리턴타입, 파라미터, 접근제어자 정보), static변수, final class변수, Constant pool(상수풀 : 문자상수, 타입, 필드, 객체참조가 저장됨)등을 분류해서 저장한다.

 

 Stack

  • Heap 영역의 객체(Object 타입) 의 데이터의 참조값이 저장됩니다
  • 원시타입의 변수와 데이터가 저장됩니다
  • Thread 별로 각각의 스텍 메모리가 할당됩니다
  • 지역 변수들은 scope에 따른 visibility를 가집니다

 

Heap

  • 원시타입이 아닌 모든 객체들(String , ArrayList ...)의 데이터(실질적인 값) 가 저장 됩니다.
  • static area에 로드된 클래스만 생성이 가능하다.

 


실제 코드들이 어떻게 저장되는지 확인해봅시다

 

public class Main {
    public static void main(String[] args) {
        int argument = 4;
        argument = someOperation(argument);
    }

    private static int someOperation(int param){
        int tmp = param * 3;
        int result = tmp / 2;
        return result;
    }
}

 

  1.  stack 에는 argument = 4 가 쌓인다
  2.  stack 에 param = 4 가 그 위에 쌓인다.
  3.  temp = 12 가 그 위에 쌓인다.
  4.  result = 6 이 그 위에 쌓인다.
  5.  argument  = 6 으로 재할당된다
  6.  someOperateion 이 끝나는 시점에서 argument를 제외한 모든 값들이 stack 에서 pop 된다.

 

이 곳의 변수들은 모두 int 라는 원시형 타입의 변수이므로 stcak 메모리에 쌓이게 되는 것입니다.

 

return result에 의해  argument 값은 업데이트 되고

 

마지막으로 stack 의 특징중 scope 에 따른 visibility 를 가진다는 특징에 의해 지역변수들은 해당 함수가 끝나는 시점에 모두 pop 되는 것입니다.

 

두번째 예는 객체를 추가해서 보겠습니다

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> listArgument = new ArrayList<>();
        listArgument.add("yaboong");
        listArgument.add("github");

        print(listArgument);
    }

    private static void print(List<String> listParam) {
        String value = listParam.get(0);
        System.out.println(value);
    }
}

 

  1.  new 연산자를 통해 힙에는 리스트가 생성되고 그 주소값은 stack에 listArgument 와 함께 쌓입니다.
  2.  add 함수를 통해 값이 추가되는데 이때 값의 자료형이 String 이므로 역시 Heap 에 저장되어집니다.  또한 array 의 해당 index와 함게 String 변수의 주소값이 저장되어 그 위치를 가리키게됩니다.
  3.  "github" 자료형 역시 2번 과정과 똑같이 반복되며 이번엔 array의 index 2 에 주소값이 저장됩니다.
  4.  print 함수의 실행과 함께 array의 실제값의 주소가 value 라는 변수명과 함께 stack에 쌓입니다
  5.  print 함수의 종료로 함게 value 변수는 사라집니다.

 

 

 

 

 마지막으로 자바의 Garbage Collection 에 대해 아주 살짝만 언급하자면 자바는 매니지드 언어의 대표주자로 자동적으로 메모리 관리를 해줍니다. 이때 heap에 데이터가 변수와 짝지어져 있지 않는다면 해당 데이터를 garbage로 판단하고 자동적으로 메모리에서 제거해줍니다.

 

 

참고한 자료

https://steady-coding.tistory.com/305