티스토리 뷰

JAVA 에서 사용되는 대표적인 메모리 영역에는 Static, Stack, Heap 영역이 있다.

JAVA를 공부하면서 그리고 Spring 을 다루면서 기본적으로 알고 있어야 하는 개념이기에, 이 세 가지의 주요 특징과 사용되는 방식에 대해 알아보도록 하자.

(실제로 Spring을 공부할 때, Static 을 함부로 쓰면 안된다고 하여 정리하게 되었다.)


 

우선, 메모리 영역에 대해 알아보기 전에 간단하게 JVM에 대해서 알아보고 가자.

 

JVM 이란?

JVM 이란 Java Virtual Machine의 약자이며, 자바 가상 머신이라고도 한다.

Java의 바이트 코드를 해석하고 실행하는 역할을 한다.

JVM 을 설치만 하면 어떠한 운영체제(OS)에서든 java 파일을 실행할 수 있다는 장점이 있다.

 

JVM 실행 순서

1. .java 파일을 컴파일러(Compiler)를 통해 .class 파일로 변환한다.

2. .class 파일을 JVM 의 ClassLoader(클래스로더)에게 보낸다.

3. ClassLoader(클래스로더)에서 JVM 런타임 영역으로 할당(로딩)하여 메모리에 올린다.

 

런타임 데이터 영역에는 5가지 영역이 존재한다.

1. Static 영역(Method 영역이라고도 한다.)

2. Heap 영역

3. Stack 영역

4. PC Register

5. Native Method Stack

 

프로그램이 실행이 되면 JVM은 OS로부터 메모리를 할당 받고, 그 메모리를 목적에 따라 여러 영역으로 나누어 관리한다.

혹여나 메모리를 관리하지 않고 구성하게 된다면 StackOverFlow 가 발생하여 애플리케이션이 종료가 되거나, 애플리케이션의 속도가 크게 저하가 될 수 있기 때문에 주의해야한다.

 

하나하나 따지고 들어가보고 싶지만, 우리가 오늘 알아볼 것은 Java 의 메모리 영역이다.

Java 메모리 영역은 크게 3가지로 이루어져 있는데, 바로 오늘 알아볼 Static, Stack, Heap 영역이다.

출처 : https://velog.io/@plz_no_anr/Java-JVM-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0

 

 

Static 영역

흔히 스태틱(Static) 이라고 부르는 이 메모리 영역은 전역변수와 정적 멤버변수, static 으로 선언된 것들이 해당 메모리 영역에 저장된다. Method(메소드) 영역이라고도 불린다.

 

Static 영역은 컴파일 시간 동안 할당 된 메모리이며 고정된 공간을 차지하며 런타임 중에는 값을 변경할 수 없다는 특징을 가지고 있다.

이 영역은 Class의 정보, Static 변수(클래스 변수), 생성자(Constructor), 메소드(Method)와 같은 것들을 저장한다.

 

Static 영역에 있는 것은 어디서든 접근이 가능하다. 그렇기 때문에 무분별하게 사용될 경우 메모리 부족 현상이 발생할 수 있다.

Static 영역은 JVM이 동작해서 클래스가 로딩될 때 생성되며, 프로그램이 종료될 때까지 메모리에 남아있게 된다.

 

 

Stack 영역

스택(Strack) 이라고 부르는 메모리 영역은 기본 자료형(int, double, boolean 등), 지역변수, 매개변수가 저장되는 메모리 영역이다.

추가적으로 객체 생성 시 참조 주소값도 저장된다.

 

자료구조 Stack의 구조로써, LIFO(Last In First Out) 방식을 취하고 있다.

LIFO란 가장 마지막에 들어간 것이 먼저 나간다는 뜻이다.

Stack 메모리에 데이터를 넣는 행위를 Push, 데이터를 내보내는 행위는 Pop 이라고 한다.

 

기본 자료형을 생성할 때 저장하는 공간으로, 임시적으로 사용되는 변수나 정보들이 저장되는 영역이다.

참조 자료형은 참조값(주소값)만 저장한다. 이 참조값은 Heap 영역에 존재하는 인스턴스(객체)를 가르킨다.

메서드를 호출할 때마다 개별적으로 스택(Stack)이 생성되며 종료시에 메모리에서 삭제된다.

 

 

Heap 영역

힙(Heap) 이라고 부르는 메모리 영역은 참조형의 데이터 객체(Object)의 실제 데이터들이 담기는 공간이다.

new 키워드로 생성된 객체와 배열이 Heap 영역에 저장된다.

Heap 영역은 참조형의 데이터 객체에 실제 데이터들이 담기는 공간이고, 실제 데이터를 가지고 있는 Heap 영역의 참조값을 Stack 영역의 객체가 가지고 있는다.

new 를 통해 인스턴스 객체를 생성했을 때, Heap 영역에는 생성된 객체가 올라가고, Stack 영역에는 해당 객체에 대한 주소 값(Reference)이 저장된다.

 

어떤 참조 변수도 Heap 영역에 있는 인스턴스를 참조하지 않게 된다면, GC(가비지 컬렉터)에 의해 메모리에서 사라지게 된다.

Heap 영역은 쓰레드가 몇개가 존재하든, 단 하나의 영역만 존재한다. (Stack 영역의 경우 쓰레드 별로 1개씩 생성된다.)

 

Instance i = new Instance("객체");

String name = "baek";

 

위 코드를 보면 변수 i 는 Stack 영역에, "객체" 에 해당하는 데이터는 Heap 영역에 적재된다고 보면 된다.

특이한 케이스로 String 도 참조형 변수이므로 name 자체는 Stack 영역에 주소 값(Reference)이 적재되고 리터럴 인 "baek" 는 Heap 영역에 적재된다.