프로세스 주소 공간
Last updated
Last updated
프로세스 메모리 모델은 기본적으로 코드, 데이터, 스택
영역으로 나뉜다.
실행할 프로그램의 명령어 코드, 제어문, 상수 등이 저장된다.
프로세스가 메모리에 로드되고 나면 더 이상 수정되지 않는다고 봐도 무방하다.
전역변수, static 변수가 저장되는 영역이다.
구체적으로는 GVAR 영역과 BSS 영역으로 나뉜다.
GVAR (Global Variable): 초기값 있는 전역변수가 저장되는 영역 BSS (Block Started By Symbol): 초기값 없는 전역변수가 저장되는 영역
런타임에 동적으로 할당되는 메모리 공간이다.
언어에 따라 malloc(), new 등의 키워드를 사용해 할당받는다.
객체와 같은 레퍼런스 타입의 데이터가 힙 영역에 저장된다.
같은 프로세스의 쓰레드들은 힙 영역의 데이터를 공유한다.
대부분의 언어에서는 힙 영역에 할당된 자원의 해제를 가비지 컬렉터가 담당한다.
반면 C, C++ 에서는 프로그래머가 직접 free 해주어야 한다.
힙 영역에 저장된 데이터의 주소값 자체는 스택 영역에 저장된다.
함수의 매개변수, 지역변수, 리턴 주소 등이 저장된다.
새로운 함수를 호출하면 새로운 스택 프레임이 생성되고 이 스택 프레임 안에 해당 함수의 데이터가 저장된다.
함수가 종료되면 스택 프레임 전체가 pop 된다.
스택에 데이터가 너무 많이 쌓여 스택의 한계를 넘어가면 스택 오버플로우 에러가 발생한다. 흔히 재귀함수 깊이가 깊어지면 확인할 수 있다.
멀티 쓰레드 환경에서 스택은 쓰레드마다 별도로 할당된다.
쓰레드는 서로 다른 함수 호출 등 독립적인 실행 흐름을 가져야 하기 때문에 스택 영역을 별도로 가진다.
자바8 이후로 추가된 영역
자바7 이전까지는 힙 영역 안의 Permanent Generation 영역에 속했었다.
Metaspace 영역은 Native Memory 에 위치한다.
힙 영역은 JVM이 관리하지만 Metaspace 영역은 OS가 관리한다.
자바 클래스 로더가 클래스 definition 등의 메타 정보를 저장한다.
코드의 수행 빈도와 복잡도 등을 고려하여 JVM이 바로 실행할 수 있는 기계어 코드 일부를 런타임 이전에 미리 컴파일 하여 캐싱 하고있는 영역이다.
cf) 자바 컴파일 과정
자바 컴파일러가 소스코드 (.java 파일) 를 바이트코드 (.class 파일) 로 변환
JIT (Just In Time) 컴파일러가 런타임에 바이트코드를 기계어로 변환
캐시 크기는 아주 작기 때문에 컴파일된 기계어 코드 전체를 저장할 수는 없다.
네이티브 코드로 작성된 라이브러리가 저장되는 영역이다.
네이티브 코드란 자바가 아닌 다른 언어 (C, C++) 로 작성된 코드를 말한다.
대표적으로 Object 클래스의 hashCode() 메소드
주로 퍼포먼스 이슈 또는 이미 다른 언어로 구현된 라이브러리를 자바로 포팅하는것을 피하기 위한 용도로 사용된다.
일반적인 쓰레드 영역과 동일하다.
효율적인 힙 메모리 관리를 위해 Young 영역과 Old 영역으로 나뉜다. (세대별 구분)
Young Generation 영역
새로운 객체 또는 생긴지 오래되지 않은 객체가 저장되는 영역이다.
가비지 컬렉션중 Minor GC가 수행되는 영역이다.
Eden 영역과 Survivor space 영역으로 나뉜다.
Eden: 새로 객체가 생성되는 영역 Survivor: Minor GC가 일어나 살아남은 객체들이 저장되는 영역. 매 GC마다 살아남은 객체들은 S0과 S1에 번갈아가며 저장된다.
Old Generation 영역
Minor GC를 여러 번 겪으면서도 계속 살아있는 객체들이 저장되는 영역이다.
가비지 컬렉션중 Major GC가 수행되는 영역이다.
#CS 스터디/운영체제/프로세스 메모리 모델#