CS

[CS] 프로그램 실행 순서(Program Flow), 메모리 구조(Memory Structure), 힙(Heap), 스택(Stack),가비지 컬렉터(Garbage Collector)

운덩하는 개발자 2023. 7. 4.
반응형

산학 프로젝트를 하기에 앞서 먼저 내가 사용하는 언어의 기본적인 메모리 관리와 누수에 유의해야하기에, 이전에 C#을 활용하여 프로그램을 짜 보았지만, 오랜만에 C#을 다루는거라 기본 개념을 단단히 잡고 프로젝트를 하기 위해 프로그램 실행 순서(Program Flow), 메모리 구조(Memory Structure), 힙(Heap), 스택(Stack),가비지 컬렉터(Garbage Collector)

프로그램 실행 순서

 

 

메모리구조

프로그램이 실행 되기 위해서는 먼저 프로그램이 메모리에 Load되어야한다.
메모리가 올라가지 않은 상태의 코드는 그저 텍스트 그 이상 그 이하도 아니다.
메모리가 올라간다는 것은 코드의 부분에 적당한 메모리가 할당이 된다
따라서 컴퓨터의 운영체제는 프로그램의 실행을 위해 다양한 메모리를 제공하며, 각각의 메모리 공간은 상호작용하며 프로그램 실행에 기여한다.
프로그램이 운영체제로부터 할당받는 대표적인 메모리 공간은 4가지가 있다.

1. 코드(Code) 영역 : 실행할 프로그램의 코드
2. 데이터(Data) 영역 : 전역(global) 변수, 정적(static) 변수
3. 스택(Stack) 영역 : 컴파일 타임에 크기 결정
4. 힙(Heap) 영역 : 런타임시 크기가 결정 (동적 할당)

**컴파일 타임 : 소스코드가 실행 가능한 기계어 코드로 변환되어 머신에서 실행 가능한 프로그램이 되는 편집 과정의 시간
**런 타임 : 컴파일 과정을 마친 프로그램이 사용자에 의해 실행되고 이러한 응용프로그램이 동작되는 시점

출처 : http://www.tcpschool.com/c/c_memory_structure


코드 영역(Code Area) 

메모리의 코드 영역은 실행할 프로그램의 코드가 저장되는 영역으로 텍스트 영역이라고도 부른다.
실행 파일을 구성하는 명령어들이 올라가는 메모리 영역으로 함수, 제어문, 상수 등이 여기에 저장된다.
CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 된다.


데이터 영역(Data) 

전역(global) 변수와 정적(static) 변수가 저장되는 영역
프로그램의 시작과 동시에 할당되고, 프로그램이 종료되어야 메모리가 소되는 영역이다.


스택(Stack)영역

 함수의 호출과 관련된 지역 변수와 매개변수가 저장되는 영역이다
스택 영역은 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸한다.

 스택 영역은 푸시(push) 동작으로 데이터를 저장하고, 팝(pop) 동작으로 데이터를 인출한다.
이러한 스택은 후입선출(LIFO) 방식에 따라 동작하므로, 가장 늦게 저장된 데이터가 가장 먼저 인출된다.

 스택 영역은 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다. (스택이 쌓이는 방향)
이렇게 스택 영역에 저장되는 함수의 호출 정보를 스택 프레임(stack frame)이라고 하며, 각각의 데이터 단위는 일반적으로 고정된 크기를 가지며, 스택 포인터(stack pointer)라는 특수한 레지스터가 스택의 상태를 추적하면서 데이터의 위치를 가리킨다.


힙(Heap) 영역

메모리의 힙(heap) 영역은 사용자가 직접 관리할 수 있는, 반드시 해야만 하는 메모리 영역이다.
힙 영역은 사용자에 의해 메모리 공간이 동적으로 할당되고 해제된다.

객체의 참조값(Object Reference)이 이 힙 영역에 저장되는 대표적인 데이터다.
흔히 자바(java), c# 등에서 사용하는 class와 그 class 객체들은 이곳에 저장된다.
힙 영역은 메모리의 낮은 주소에서 높은 주소의 방향으로 할당된다. (스택이랑 반대 방향, 힙낮높)


메모리간 상호작용(Memory Interaction) - Feat Stack, Heap

사실 스택 영역과 힙 영역은 같은 공간을 사용한다.
그러기에 스택 영역이 클 수록 힙 영역이 작아지고, 힙 영역이 클 수록 스택 영역이 작아진다.

스택 영역이 높은 주소 -> 낮은주소로 할당되고, 힙 영역이 낮은주소 -> 높은 주소(힙낮높 이렇게만 외우자)로 할당되기 때문에 자신의 영역이 상대의 영역을 침법하는 사태가 발생할 수 있다. 이를 각각 스택 오버플로우, 힙 오버플로우 라고 한다.



스택 (Stack)

힙(heap) 영역에 생성된 Object 타입의 데이터 참조값이 할당된다.
원시 타입의 데이터가 값과 함께 할당된다. 원시 타입의 데이터는 Heap 메모리에 할당되지 않는다.
원시타입 : byte, short, int, long,double, float, boolean, char 타입 지역변수들은 scope에 따른 visibility를 가진다.
각 Thread는 자신만의 stack을 가진다.


힙 (Heap)

 힙 영역에는 주로 긴 생명주기를 가지는 데이터들이 저장된다( 대부분의 객체는 크기가 크고 서로 다른 코드블럭에서 공유되는 경우가 많다.)
애플리케이션의 모든 메모리 중 stack에 있는 데이터를 제외한 부분이라고 보면 된다.
모든 Object 타입(Integer, String, ArrayList...)의 참조 값은 데이터 타입과 함께 heap 영역에 생성된다.

  Wrapper class에 해당하는 Integer, Character, Byte, Boolean, Long, Double, Float, Short 클래스는 모두 Immutable (변경 불가)이다. Wrapper Class는 아니지만 String 클래스 역시 변경부가하므로 힙에 있는 같은 오브젝트를 레퍼런스하고 있더라도 새로운 연산이 적용되는 순간 새로운 객체가 heap에 재 할당된다.

 새로운 객체가 heap에 할당되더라도 stack에서 이를 참조하지 않으면 가비지 컬렉션의 대상이 된다.
heap 영역에 있는 객체들을 가리키는 참조 변수는 stack에 올라가게 된다.


가비지 컬렉터(Garbage Collector)

 객체지향 프로그래밍 언어는 메모리를 동적으로 할당한다는 개념이 존재하고, 런타임에 동적으로 할당된 메모리를 해제해주어야만 한다. c++는 Modern C++이 되어서야 스마트 포인터라는 기술의 등장으로 이를 비교적 나은 형태로 처리할 수 있게 되었지만, 아직 '자동'으로 해준다고 보기는 어렵다.

 C#으로 작성한 코드는 .NET 위에서 실행되며 CLR을 통해 자동으로 필요없는 동적 메모리를 해제하는 GC(Gabage Collector)를 지원한다. 

** CLR(Common Language Runtime) : .NET 언어로 작성된 애플리케이션의 실행 환경 제공, 코드 실행, 메모리 관리, 예외 처리, 보안 및 타입 안정성 등 관리

작동원리

메모리 할당 패턴을 추적하고, 더 이상 사용되지 않는 객체인 '가비지(Garbage)'를 식별
가비지 컬렉터는 
 

Reference
https://luv-n-interest.tistory.com/922:

http://www.tcpschool.com/c/c_memory_structure

 

반응형

댓글