본문 바로가기

개발 코딩 정보 공유/안드로이드 자바 코틀린

자바 메모리 Stack 과 Heap 영역에 대하여

 

 

 

 

 

 

 

안드로이드 지식 공유

 

 

 

자바 메모리 영역 - stack and heap

 

 

그냥 만들어도 만들수 있습니다. 그렇지만 알고 만드는 것과 알고 만드는 것은 많은 차이가 있죠. 개발시 가장 기본이자 기본. 메모리 구조. 정말 중요하지만 쓰다보면 까먹는 게 또 바로 이 메모리 영역에 대한 이해 입니다. 눈에 보이지 않기 때문이죠...ㅠㅠ 자바는 메모리 관리를 따로 해줄수가 없습니다. 순전히 가비지 컬렉션에 의지해서 잘 관리 해주길 바랄 뿐이죠 ^^;;;;;;;

 

자바 메모리 영역은 여러가지가 있지만 오늘은 크게 두가지로 나누어 알아보겠습니다. 바로 stack과 heap 입니다. 스택은 말 그대로 메모리에 정보를 쌓는 구조로 설계 되어 있죠. 그에 반면 heap에 있는 데이터는 반드시 주소(참조)값이 있어야 원하는 위치를 찾아 갈 수 있습니다. 저도 맨날 헷갈리는 부분인 ㅠㅠ [stack]과 [heap]에 대해 정리해 보겠습니다.

 

stack은 전형적인 LIFO(Last in First Out) 구조로써... 다들 아시다시피 ?? 이놈은 마지막에 들어온 놈이 제일 먼저 나가게 되는 구조입니다. 우리 일상에서 찾아보면, 책상에 쌓아둔 책을 예를 들 수 있겠네요. 10권의 책을 차곡차곡 쌓아두면 10번째 책이 제일 위에 있게 되고 그 책을 바로 펼쳐 볼수 있다.(순전히 맨위책부터 본다는 가정하에...)

heap 은 쉽게 말해 공유 메모리 라고 생각 할 수 있습니다.(static 아님) 전역적인 접근이 가능하며 데이터를 지속하는 특징을 가집니다. 영속적인건 아닙니다. 왜냐 가비지 콜렉션이 맘에 안들면 없애 버리기 때문이다.^^;;;

 

Stack 영역은 Thread 와도 밀접한 관계가 있는데요. 이게 무슨 말이냐면 쓰레드 별로 지역스택영역을 가진다는 말이죠. 스택영역에는 메서드내에 정의한 각종 변수들과 파라메터들이 계산될텐데요. 그 부분이 여러개의 멀티 쓰레드들이 침범한다고 생각해보시죠. 쉽게 말해 A라는 변수(예를 들어 int i = 0을 + - 하는 여러 쓰레드의 경우) 를 여러놈들이 조작한다는 말이죠. 결과가 생각만해도 끔찍 하네요. (전혀 다른예상치 못한 값이 나올겁니다.) 메서드내의 로직이 끝나면 스택에 할당 되었던 변수들은 다 사라집니다. 임무를 마치면 메모리에 가지고 있을 필요가 없는거죠.

 

힙에는 new 키워드를 통해 생성되는 객체와 각종 스트링들이 힙에 저장됩니다. 이는 쓰레드 내에서만 사용하는 스택과 다른점이죠. 힙은 전역적으로 사용이 가능하여 쓰레드들 사이에 데이터를 공유하게 됩니다. A obj = new A(); 라는 객체를 생성한뒤 여러개의 쓰레드가 이 객체를 가져다 쓸 수 있는 것이죠. 그래서 쓰레드 사이의 동기화를 하는 이유가 여기에 있습니다. 

 

스트링(문자들)의 경우 조금 특이한 케이스로써 여기에 저장됩니다. 스트링은 스트링풀이라는 힙내의 공간에 할당되기도 하죠. 이 부분은 일단 넘어가고 스트링의 경우 다시 포스트를 작성해서 올려보겠습니다. 아래의 그림을 한번 보시면 이해가 빠르겠네요. 

 

 

 

 

 

 

 

일단 그림상태는... 죄송...

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
private A aaa = new A(); //멤버변수 힙 저장/공유
 
public static void main(String[] args) { 
int i=0; //지역변수 스택에 저장
Object obj1 = new Object(); //스택 포인트 참조값 -> 힙 객체로 연결
Object obj2 = new Object(); //스택 포인트 참조값 -> 힙 객체로 연결
foo(obj2);
 
 
private void foo(Object param) { 
System.out.println(param.toString());
cs

 

 

int i = 0 같은 원시 타입은 스택에 저장됩니다. obj1, obj2  는 new 키워드로 생성하였으니 힙에 생성되죠. str의 경우 조금 특이 한데요. " " 을 통해 문자열을 생성하게 되면 힙 내부의 스트링 풀이라는 곳에 생성 되게 됩니다. new String("ABC"); 로 생성하게 되면 스트링 풀에 있는지 확인후 스트링풀에도 생성되고 힙에도 생성됩니다. 복잡하네요. 이처럼 우리가 그냥 사용하는 코드들 이지만 내부에서는 이런 복잡한 설계에 의해 동작하고 있네요. 다음 편에서는 스트링과 메모리관련되서 더 정리해 보겠습니다.