전 포스트에 이어 바로 이어가겠습니다.
사실 이 부분이 흥미로웠습니다.
고등학교 시절때 C에 대해 간단히 공부했었던 기억이 있는데, 그당시에는 뭣모르고 배웠으며 정적 구역, 동적 구역이라든지
스택, 메모리, 스태틱을 거의 한귀로 듣고 한귀로 흘렸기에 익숙하지만 생소한 단어들이었습니다.
예시는 항상 가까운 것 부터
이에 대해 책에서는 마침 자바, C 어느 언어든 빠질 수 없는 main 함수를 예시로 들어 이해하기 편했습니다.
public class Start {
public static void main(String[] args) {
System.out.println("Hello OOP!!!");
}
}
간단한 코드를 통해 어떻게 main() 메서드가 작동을 하는지, 내부에서는 어떤 일이 일어나고 있는지 알아보겠습니다.
이것 또한 그림으로 예시를 보겠습니다.
그렇다면 "Hello OOP!!!"를 출력한 후의 메모리는 어떻게 될까?
놀랍게도 그대로 입니다.
그 이유는 main() 메서드의 스택 프레임이 생기는 것이며, "{" 중괄호로 스택 프레임이 생성되며 "}" 중괄호로 스택 프레임이 소멸하기 때문입니다.
즉, main() 메서드의 스택프레임이 아직 닫히기 않았기 때문에 그대로 인것입니다.
다시 말해 main() 메서드의 스택 프레임을 닫는다면?
위 그림과 같이 스택프레임이 소멸하게 되어 main() 메서드가 종료 되고, JRE는 JVM을 종료하며 JRE 자체또한 운영체제 상의 메모리에서 사라지게 됩니다.
변수또한 main() 메서드와 같이 스택 프레임 안에 존재하게 됩니다.
public class Star2 {
public static void main(String[] args) {
int i;
i = 10;
double d = 20.0;
}
}
이 또한 백문이 불여일견, 그림으로 설명하겠습니다.
위 그림과 같이 main() 메서드 내부에 생성된 변수들은 main() 스택 프레임 안에 존재하게 됩니다.
그렇다면 위와 동일하게 main() 메서드가 끝나는 동시에 같이 소멸하게 됩니다.
뭔가 "블록", "스택" 들어가면 어려운 것 처럼 느껴집니다.
하지만 내부를 보면 그냥 방 나누는? 그런 간단한 단어들 입니다.
public class Start3 {
public static void main(String[] args) {
int i = 10;
int k = 20;
if(i == 10) {
int m = k + 5;
k = m;
} else {
int p = k + 10;
k = p;
}
//k = m + p;
}
}
위 코드 또한 그림으로 보여드리겠습니다.
그렇다면 밑에서 3번째 줄인
//k = m + p;
라고 물어본다면 지역변수에 대해 조금이라도 공부한 개발자라면 당연히 "지역변수니까요" 라는 답변을 할것입니다.
하지만, 이것을 스택 프레임으로 설명하라 하고, 또한 전역변수로 바꾸는 과정을 설명하라한다면?
물론 이 글을 끝까지 읽는다면 설명할 수 있을겁니다.
하지만 저도 이 책을 읽기 전에는 생각도 못해봤으며 설명 또한 못했을 것 입니다.
위에서의 문제를 해결하기 위해선 가장 간단한 방법은 "전역변수"를 사용하는 것입니다.
현재 위 코드는 짧기때문에 가독성도 좋고 한번에 찾을수 있지만, 코드의 규모가 점점 늘어나며 변수의 갯수도 늘어나기에
인간인 이상 헷갈릴 겁니다.
그러기에 꼭 사용해야하는 상황이 아니라면 사용하지 않는 것이 좋습니다.
머리에 잘 기억남기 위해선 코드로 남기는 것이 최고기에 전역변수 또한 예제를 들겠습니다.
public class Star5 {
static int share;
public static void main(String[] args) {
share = 55;
int k = fun(5, 7);
System.out.println(share);
}
private static int fun(int m, int p) {
share = m + p;
return m - p;
}
}
순서대로 설명해드리겠습니다.
share = 55;
로 선언만 되어있는 share 변수에 55를 할당합니다.
int k = fun(5,7);
이 코드로
위 그림에는 main() 스택 프레임 안에 있는 k 변수에 초기화가 되어 있지 않지만,
fun() 스택 프레임이 끝남과 동시에 k에는 2가 할당될 것입니다.
절차 지향(PP) 인 C언어와 다르게 객체 지향(OOP) 인 Java는 변수 생성 후에 함수를 선언해도 불러오는 것이 가능합니다.
그러기에 fun 함수안에 있는
share = m + p;
으로 share 에는 5 + 7 값인 12가 들어가게 됩니다.
멀티 스레드란 T메모리 모델의 스택 영역을 스레드 개수만큼 분할해서 쓰는 것입니다.
멀티 프로세스란 다수의 데이터 저장 영역, 즉 다수의 T 메모리를 갖는 구조입니다.
이 둘의 차이점은?
ㆍ멀티 프로세스 > 각 프로세스마다 각자의 T 메모리가 있고 각자 고유의 공간이므로 서로 참조 X
ㆍ멀티 스레드 > 하나의 T 메모리만 사용하는데 스택 영역만 분할해서 사용하는 구조
챕터 정리
ㆍ스태틱 : 클래스의 놀이터
ㆍ스택 : 메서드의 놀이터
ㆍ힙 : 객체의 놀이터
느낀점 알게된점
앞으로 개발에 있어 가장 중요한 부분인 스택, 메모리, 스태틱등 다시 되짚어보며 개념을 제대로 쌓을수 있어 좋았습니다.
특히 스택, 메모리에 대해 간단하게나마 지식을 얻은것 같습니다.
해당 내용은 스프링 입문을 위한 자바 객체 지향의 원리와 이해를 참고하여 작성되었습니다.