큐(Queue), 스택(Stack), 힙(heap)

Jan 28, 2024
큐(Queue), 스택(Stack), 힙(heap)

1. 큐 (Queue) 란?

데이터 자료구조 중 하나로, 데이터를 선입선출의 원칙에 따라 처리하는 구조 데이터를 한쪽 끝에서만 삽입하고, 다른 한쪽 끝에서만 삭제하는 동작을 수행한다. 따라서, 가장 먼저 들어온 데이터가 가장 먼저 처리되는 구조이다. (ex. 화장실 줄서기)
 

2. 스택 (Stack) 이란?

데이터를 저장하는 자료구조 중 하나. 후입선출. 가장 나중에 들어온 데이터가 가장 먼저 처리. '메소드'가 호출될 때, 큐와 함께 생성되며, '메소드'가 종료될 때, 큐와 함께 사라진다. 3대 저장공간 중 수명이 제일 짧다. 생명주기가 해당 메소드가 실행될 때 ~ 끝날때 뿐. 아주 잠깐! 생겼다가 사라짐.
notion image
 
중괄호 { } 가 있으면 Queue와 Stack이 생김. (ex. if, for) 다 스택이다~ 이 중괄호 밖에선 int n2 사용 못함. stack이라 쓰려고 보면 사라지고 없기 때문... if (n1 == 1) { int n2 = 2; <<if의 stack }
notion image
 

 
💡
<데이터를 저장할 수 있는 공간> - 모두 scope 1. static 2. heap 3. stack <생명 주기> - static이 제일 길다.
· stack < heap < static
 

 

2. 큐 & 스택 설명

설명 보기
notion image
3번까지 실행된 이후 큐와 스택이 등장

2-1. 큐와 스택 상세도

notion image
notion image
'메소드'가 실행되면서 큐(Queue)가 열린다. main메소드에서 실행되면 main Queue라고 하고, m1 메소드에서 실행되면 m1 Queue라고 메소드의 이름을 따서 큐의 이름을 붙인다. main 메소드가 실행되는 동안에는 main 큐에서 해당 코드 블록 (18 ~ 24)이 순차적으로 실행. (main이 실행된다 = main 큐에서 코드가 실행된다)
main에 있는 18, 19, 20, 21... 의 라인들이 큐에 담기는 걸 'put'(=데이터를 추가하는 동작) 큐에 담긴 데이터들을 던지는 걸 'pop' (= 메모리에서 데이터 제거, = 실행 종료, = 메모리에 있는걸 꺼내서 cpu한테 전달) * 메모리에 있는 데이터들이 cpu에 가야 작동
notion image
 
19번 라인은 메소드를 호출하는 코드다. 이 라인이 실행되면서(=큐 하면서) 9번과 10번 라인이 메모리에 뜨게 되는데 이때 m1의 값이 m1이라는 stack이 만들어지면서 이곳에 저장(push) 된다. * 처음에 스캔할 때는 m1이라는 이름만 메모리에 떠있는 상태. 이후 main 큐의 호출을 통해서 m1이 가지고 있는 데이터 값(9,10 라인)이 열리는데, 그 값이 stack에 임시저장 되는 것! 이 값이 static에 저장 돼?! heap에 저장 돼!? 안되잖아. stack에 저장해야지
실행이 종료되면서(=pop이 되면서) m1 stack도, m1 Queue도 같이 다 사라진다. 이게 바로 '지역변수' (=stack에서 만들어지는 변수가 지역변수!) * stack이 사라질 때, stack에 저장해뒀던 값을 전달받고 싶으면 return을 사용한다. return이 있으면 큐가 바로 사라지지 않고 19번 라인 실행 > 9, 10라인 실행 > 19번 실행 > 종료 return이 없으면 19번 라인 실행 > 9, 10라인 실행 > 20번 라인 실행
 

 
💡
Queue - 코드를 순서대로 실행하려고 만들어짐 Stack - 그 큐를 실행할 때 데이터를 임시 저장하기 위해 만들어짐
💡
* 큐는 저장 공간이 아니다! * 큐의 크기는 라인에 비례한다! * 메인 큐가 닫힌다 = 프로그램이 종료
💡
메소드 이름 = 4byte
 

3. 접근 방식

stack은 stack끼리 접근이 불가능함. 다른 공간(외부)에서도 stack에는 접근할 수 없다. 다른 공간에서 찾으려고 해도.. 실행될 때만 잠깐 떴다가 죽어버려서...찾을 수 있는 방법이 없음. m1 stack은 m1에서만 찾을 수 있음. 생명주기가 제일 짧음. 대신 메모리 많이 안먹음
static은 stack에 우회적으로 접근 가능. > (클래스명.메서드 변수명) 형식으로. (ex. ScopeEx01.m1 이런식으로 접근) static은 어디에서든지 다 찾을 수 있지만 메모리를 많이 먹는다.
notion image
static (n2=2, m1(), main) > 클래스명.x 로 접근 > 어디에서든지 접근 가능하다 heap (n1=1, m2()) > heap끼리는 같은 scope여서 접근 가능하다 stack (n5 = 10) > 외부 접근 불가능
 
notion image
14번 라인, n2는 힙이 힙에 찾는 것. (찾는 것과 저장하는 건 다르다)
 

 
💡
같은 scope에 동일한 변수명을 사용할 수 없다. (에러!)
notion image
 

4. heap

notion image
notion image
 

4-1. heap 상세도

notion image
m1은 19번 라인에 있는데… 그림 잘못 그렸쥬?
 
heap은 new로 메모리에 띄운다. ScopeEx01 sc = new ScopeEx01(); 처럼 new로 메모리에 띄우면, 1. n1, m2같이 static이 안붙어 있는 모든 애들이 heap에 뜸 (그냥 남는 공간 찾아서 뜸) *메서드(m2)는 이름만 heap에 뜬다. 2. sc라는 변수는 main stack에 만들어짐. 값이 아닌 sc라는 주소번지가 저장됨. (이게 바로 포인터. 저장될때 *5000 이런 식으로 앞에 *가 붙는다.) +) sc2는 sc2라는 주소번지가 main stack에 저장되고, heap에는 n1 = 1, m2 라고 똑같은 값이 저장된다. > 클래스를 마구 찍어낼 수 있다.
* heap영역으로 실행된 애들은 static을 따라가지 않음 > System.out.println(sc.n1);에서 n1은 static이 붙어있지 않은 (=heap에 띄워진) n1 값을 가짐 * 만약, heap에 띄워진 애가 없으면 static을 따라감 > 아래 그림으로 설명 (heap이 떠있으면 heap에 있는걸 우선적으로 찾는듯)
notion image
int n1 = 1; 가 없어서 static int n1을 n1값으로 받음
int n1 = 1; 과 static int n1을 동시 선언하면 에러
(변수명 중복)
 
notion image
//결과값 11 나온 것 확인
💡
Heap은 꼭 heap 변수명 (stack에 있는) 으로만 찾을 수 있음. 걔가 heap 공간을 가리키는 주소값이니까
 

 
💡
* stackoverflow > 스택의 메모리 공간을 다 쓰면 뜸
(스택이 pop이 되지 않고 계속 쌓이다가 넘치면 스텍오버플로우)
 
* 매개변수도 stack에 만들어짐 static void gugudan(int x) { for (int i = 1; i <= 9; i++) { System.out.println(x + "*" + i + "=" + (x * i)); } System.out.println(); } 라면 (int x) 이것도 stack에... 외부에서 못찾음
 
Share article

More articles

See more posts

codingb