[Java] - 메모리구조

백엔드류·2024년 5월 29일

Java

목록 보기
6/6
post-thumbnail

자바 프로그램이 실행되면 JVM은 OS로부터 메모리를 할당받고, 그 메모리를 용도에 따라서 여러 영역으로 나누어 관리를 한다.
JVM의 메모리 공간은 크게 Method(Static), Stack, Heap 영역으로 구분되고 데이터 타입에 따라 각 영역에 나눠서 할당 되게 된다.



자바 변수의 종류

메모리 영역을 알기 전에 자바에서 선언 위치에 따른 변수의 종류를 알아보자.
변수는 크게 네 종류가 있다. 클래스 변수, 인스턴스 변수, 지역변수, 매개변수이다.

public class prc {


    private int state = 0;      //인스턴스 변수
    
    public static int gage = 100;   // 클래스변수
    
    public static void main(String[] args) {       //매개변수
        
        int a = 10;  // 지역변수
        
    }
}

(1) 클래스 변수(static 변수)

  • 선언위치 : 클래스 영역
  • 객체를 공유하는 변수로 여러 객체에서 공통으로 사용하고 싶을 때 정의

(2) 인스턴스 변수

  • 선언위치 : 클래스 영역
  • 클래스 영역에서 static이 아닌 변수
  • 개별적인 저장 공간으로 객체 / 인스턴스 마다 다른 값 저장 가능
  • 객체/인스턴스 생성만 하고 참조 변수가 없는 경우 가비지 컬렉터에 의해 자동 제거됨

(3) 지역 변수

  • 선언위치 : 메서드 영역
  • 메서드 내에서 선언되고 메서드 수행이 끝나면 소멸되는 변수초깃값을 지정한 후 사용할 수 있음

(4) 매개 변수

  • 선언위치 : 메서드 영역
  • 메서드 호출 시 '전달하는 값'을 가지고 있는 인수(지역 변수처럼 선언된 곳부터 수행이 끝날 때까지 유효함)


각 변수의 생성시기

  • 클래스변수 : 클래스가 메모리에 올라갈 때
  • 인스턴스 변수 : 인스턴스가 생성되었을 때
  • 지역변수/매개변수 : 위치하고 있는 메서드가 수행되었을 때


Method(Static) 영역

  • JVM이 동작해서 클래스가 로딩될때 생성
  • JVM이 읽어들인 클래스와 인터페이스에 대한 런타임 상수 풀, 멤버 변수(필드), 클래스 변수(Static 변수), 상수(final), 생성자와 메소드 등을 저장하는 공간
  • Method 영역의 데이터는 프로그램의 시작부터 종료가 될 때까지 메모리에 남아있다. 그러나 static 데이터를 무분별하게 많이 사용할 경우 메모리 부족 현상이 일어날 수 있게 된다.
  • static 메소드, static이 아닌 메소드 모두 메소드 영역에 저장된다.

Stack 영역

  • 메소드 내에서 정의하는 기본 자료형에 해당되는 지역변수의 데이터 값이 저장되는 공간
  • 메소드가 호출될 때 스택 영역에 스택 프레임이 생기고 그 안에 메소드를 호출
  • 원시 타입의 데이터에 해당되는 지역변수, 매개변수 데이터 값이 저장된다.
  • 메소드가 호출 될때 메모리에 할당되고 종료되면 사라짐
  • 후입선출의 특성을 가지며, 스코프의 범위를 벗어나면 스택 메모리에서 사라진다.
    • 스택 프레임이란?
      하나의 메서드에 필요한 메모리 덩어리를 묶어서 스택 프레임(Stack Frame)이라고 한다.
      하나의 메서드당 하나의 스택 프레임이 필요하며, 메서드를 호출하기 직전 스택프레임을 자바 Stack에 생성한 후 메서드를 호출하게 된다.
      스택 프레임에 쌓이는 데이터는 메서드의 매개변수, 지역변수, 리턴값 등이 있다.만일 메서드 호출 범위가 종료되면 스택에서 제거된다.

Heap 영역

  • JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역
  • 참조형 데이터 타입을 갖는 객체(인스턴스), 인스턴스 변수, 배열 등이 저장되는 공간
  • Heap 영역은 Stack 영역과 다르게 보관되는 메모리가 호출이 끝나더라도 삭제되지 않고 유지된다.
    • 그러나 어떤 참조 변수도 Heap 영역에 있는 인스턴스를 참조하지 않게 된다면, 가비지 컬렉터에 의해 메모리에서 청소된다.
  • Stack은 스레드 갯수마다 각각 생성되지만, Heap은 몇개의 스레드가 존재하든 상관없이 단 하나의 Heap 영역만 존재


마무리

  • 마지막 코드가 실행되면 main 스택 프레임은 스택 영역에서 제거된다.
    • 스택 영역은 메서드의 끝을 알리는 닫는 중괄호를 만나면 자동으로 메모리에서 제거된다.
    • 그러나 힙 영역에는 여전히 객체 데이터가 메모리에 상주되게 된다.
    • 가비지 컬렉터는 힙 영역에 참조되지 않고 남아버린 고아 객체들을 식별해 힙 영역을 청소해준다.
    • 추가로 코드 실행이 모두 끝나면 Method(Static) 영역도 비워지게 된다.
  • 힙 메모리는 애플리케이션의 모든 부분에서 사용되며, 반면에 스택 메모리는 하나의 스레드가 실행될 때 사용. 그래서 힙과 메소드 공간에 저장된 객체는 어디서든지 접근이 가능하지만, 스택 메모리는 다른 스레드가 접근할 수 없다.
  • 언제든지 객체가 생성되면 항상 힙 공간에 저장되며, 스택 메모리는 힙 공간에 있는 객체를 참조만 한다. 즉, 스택 메모리는 원시 타입의 지역변수와 힙 공간에 있는 객체 참조 변수만 갖고 있다.
  • 스택메모리의 생명주기는 매우 짧으며, 힙 메모리는 애플리케이션의 시작부터 끝까지 살아남는다.
  • 자바 스택 메모리 사이즈는 힙 메모리와 비교했을 때 매우 적다. 하지만 스택 메모리는 간단한 메모리 할당 방법(후입선출)을 사용하므로 힙 메모리보다 빠르다.


참고 : https://inpa.tistory.com/entry/JAVA-☕-그림으로-보는-자바-코드의-메모리-영역스택-힙 [Inpa Dev 👨‍💻:티스토리]

profile
공부한 내용을 정리한 블로그입니다 & 백엔드 개발자

0개의 댓글