정적 매서드와 클래스 매서드의 차이점에 대해서 알아보자.
리눅스에서는 빌드된 어플리케이션의 프로세스는 어떻게 생겼을까
리눅스에서 하나의 프로세스는 4개의 영역을가진다
DATA
HEAP
STACK
TEXT
빌드가 되고나면 가장 먼저 STATIC한 글로벌 변수들을 DATA영역에 저장한다.
선언만 되고 초기값이 없는 변수의 경우 BSS영역에 담긴다
컴파일과 링크(빌드과정에 대한 설명은 생략함) 이후에 실행파일안의 코드가 들어가는곳이라고 봐도 될거 같다.
우리가 작성한 코드가 읽히는 곳이다.
CPU는 Program Counter에서 가 가지고있는 메모리상의 주소를 통해서 순차적으로 TEXT영역에 있는 코드를 처리한다.
처리하다가 함수를 만나면 PC는 함수 다음코드의 메모리상 주소를 가지고 있는 상태로 STACK으로 함수를 넘긴다
TEXT에서 코드가실행되다가 STACK으로 넘어오면 이 함수가 종료되고 다시 다시 돌아가야할(return) 코드가 STACK의 가장 위에 쌓인다.
먼저 STACK에서 사용되는 레지스터들을 알아보자
스택안에서 함수의 최상단 스택포인터를 가지고 있다
다음과 같은 상황을 가정해보자
- func1안에서 func2를 호출
- func2안에서 func3를 호출
- func3는 안전하게 return
- 다시 func2로 돌아와서 func4를 호출
- func4를 실행하다가 error발생
위와같은 경우에 STACK에서는 어떻게 진행과정을 tracking할것인가?
여기서 EBP레지스터가 활용된다.
STACK안에서 새로운 함수가 실행될 때, EBP레지스터는 함수가 호출 될 때 최상단의 Stack Pointer의 주소를 가지고 있다.
즉, 실행하던 함수에 문재가 생겼을 때 어떤함수에서 문제가 났는지 빠르게 tracking 하기 위해서 존재한다
STACK에서 함수의 실행으로 인해 나온 return 값을 저장한다
다시 돌아와서 위와같은 레지스터들의 도움을 받아 스택에서는 Stack Pointer에 의해서 함수가 순차적으로 실행된다.
함수의 실행 도중 갑자기 글로벌 변수를 할당한다면?? DATA영역에 들어가게 될까? DATA영역은 컴파일단계에서 이미 글로벌 변수들을 넣어둔 곳인데 여기 할당이 가능할까?
STACK에서 글로벌 변수가 할당되었다면 HEAP영역에 동적으로 해당 변수에 대한 메모리가 할당되어 생성된다.
즉, HEAP을 사용하는 이유는 변수가 함수와 생명주기를 같이하기를 원하지 않아서이다. 함수의 실행도중에 지속적으로 메모리에 공간을 차지하고 있는 변수를 생성하고 싶으면 HEAP을 사용하면된다
메모리 구조에 대한 설명이 되었다고 생각하니 다시 이 논쟁으로 돌아와보자
우선 Static Method는 어플리케이션의 빌드와 동시에 DATA영역에 할당된다. 그 말은 메인 프로세스와 Static Method는 생명주기를 같이함을 의미한다.
Class Method는 HEAP영역에 할당된다고 한다. 이는 프로그래밍 언어에서 지원되는 Garbege Collector의 알고리즘에 의해서 (프로그램의 성능을 위해서) 지워질 여지가 있다. 즉, 프로그램 성능을 control하는 watcher의 관리하에 있음을 뜻한다.
무엇을 사용해야할지는 개발자의 상황에 달려있다고 생각한다