스프링 입문을 위한 자바 객체 지향의 원리와 이해 - Chapter 02. 자바와 절차적/구조적 프로그래밍 Ep_2

김광현·2022년 12월 27일
0

전 포스트에 이어 바로 이어가겠습니다.

우선 가장 가까운 Java main함수가 어떻게 굴러가는지

사실 이 부분이 흥미로웠습니다.
고등학교 시절때 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 메모리만 사용하는데 스택 영역만 분할해서 사용하는 구조

또한 멀티 프로세스는 서로 참조가 불가능해 안전한 구조지만, 메모리 사용량은 그만큼 크다.

반대로 멀티 스레드는 하나의 T 메모리 안에서 스택 영역만 분할한 것이기에 다른 스레드의 영역에는 접근할 수 없지만,

스태틱 영역과 힙 영역은 공유해서 사용하는 구조다. 따라서 멀티 프로세스 대비 메모리를 적게 사용할 수 있는 구조다.


챕터 정리

이번 챕터에서 메모리, T메모리가 많이 언급되었는데 이 단어가 익숙해져야 앞으로에 있을 3챕터에서 이해하기 편합니다.

또한 이챕터에서 중요한 키워드 3개를 언급하며 마무리하겠습니다.

ㆍ스태틱 : 클래스의 놀이터
ㆍ스택 : 메서드의 놀이터
ㆍ힙 : 객체의 놀이터

느낀점 알게된점

앞으로 개발에 있어 가장 중요한 부분인 스택, 메모리, 스태틱등 다시 되짚어보며 개념을 제대로 쌓을수 있어 좋았습니다.
특히 스택, 메모리에 대해 간단하게나마 지식을 얻은것 같습니다.

해당 내용은 스프링 입문을 위한 자바 객체 지향의 원리와 이해를 참고하여 작성되었습니다.

profile
대림대학교 컴퓨터정보학부

0개의 댓글