Gidhub BE Developer

메모리 구조(Memory Structure)

2018-10-07
goodGid

메모리 구조란?

  • 프로그램이 실행되기 위해서는

  • 먼저 프로그램이 메모리에 로드(load)되어야 한다.

  • 또한 프로그램에서 사용되는 변수들을 저장할 메모리도 필요하다.


  • 따라서 컴퓨터의 운영체제는

  • 프로그램의 실행을 위해

  • 다양한 메모리 공간

  • 제공하고 있다.

  • 프로그램이 운영체제로부터 할당받는 대표적인 메모리 공간(RAM)은 다음과 같다.

  1. 코드(code) 영역

  2. 데이터(data) 영역

  3. 스택(Stack) 영역

  4. 힙(Heap) 영역


코드(Code) 영역

  • 메모리의 코드(code) 영역

  • 실행할 프로그램의 코드가 저장되는 영역으로

  • 텍스트(code) 영역이라고도 부른다.


  • 실행할 프로그램의 코드는

  • 프로그래머가 작성한 소스 코드이다.

  • 프로그램이 시작하고

  • 끝날 때까지 메모리에 계속 남아있는다.


  • 또한 상수도 여기에 들어간다.

  • 물론 컴파일 된 기계어가 들어간다.


  • CPU는

  • 코드 영역에 저장된 명령어를

  • 하나씩 가져가서 처리하게 된다.


데이터(Data) 영역

  • 메모리의 데이터(data) 영역

  • 프로그램의 전역 변수정적(Static) 변수가 저장되는 영역이다.

  • 프로그램이 시작하고

  • 끝날 때까지 메모리에 계속 남아있는다.


스택(Stack) 영역

  • 메모리의 스택(stack) 영역

  • 함수의 호출과 관계되는

  • 지역 변수매개변수가 저장되는 영역이다.


  • 스택 영역은 함수의 호출과 함께 할당되며

  • 함수의 호출이 완료되면 소멸한다.

  • 이렇게 스택 영역에 저장되는 함수의 호출 정보

  • 스택 프레임(Stack frame)이라고 한다.


  • 스택 영역은

  • 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다.

  • 프로그램이 자동으로 사용하는 임시 메모리 영역이다.


  • Stack 영역이 클 수록 Heap 영역이 작아지고

  • Heap 영역이 클 수록 Stack 영역이 작아진다.


  • 스택 영역은

  • 컴파일 시크기결정된다.

스택 할당 속도 vs 힙 할당 속도

  • 스택훨씬 더 빠르다.

  • 스택은 이미 할당 되어 있는 공간을 사용하는 것이고

  • 은 따로 할당해서 사용하는 공간이다.

  • 다만 스택은 공간이 매우 적기 때문에

  • 모든 응용에서 스택을 사용할 수는 없다.


  • 좀 더 자세히 알아보자.

  • 스택에서 할당의 의미는

  • 이미 생성되어 있는

  • 스택에 대해

  • 포인터의 위치만 바꿔주는

  • 단순한 CPU Instruction(단순히 덧셈과 뺄셈 연산, 일반적으로 단일 Instruction)이다.

  • 반면 에서의 할당

  • 요청된 chunk의 크기, 현재 메모리의 fragmentation 상황 등

  • 다양한 요소를 고려하기 때문에

  • 더 많은 CPU Instruction이 필요하다.

장점

  • 낭비되는 공간이 없다.

  • 하나의 명령만으로

  • 메모리 조작어드레스 조작이 가능하다.

단점

  • 한계가 있어

  • 한계를 초과하도록 삽입할 수 없다.

  • 유연성이 부족하다.


힙(Heap) 영역

  • 메모리의 힙(Heap) 영역

  • 사용자직접 관리할 수 있고

  • 해야만하는 영역이다.


  • 힙 영역은

  • 사용자에 의해

  • 메모리 공간동적으로

  • 할당되고 해제된다.


  • 힙 영역은

  • 메모리의 낮은 주소에서 높은 주소의 방향으로 할당된다.

  • malloc() 또는 new 연산자를 통해 할당하고

  • free() 또는 delete 연산자를 통해서 해제가 가능하다.


  • Java에서는 가비지 컬렉터

  • 자동으로 해제하는 곳이다.


  • Stack 영역이 클 수록 Heap 영역이 작아지고

  • Heap 영역이 클 수록 Stack 영역이 작아진다.


  • 런타임 시크기결정된다.

장점

  • 프로그램에 필요한

  • 개체의 개수크기

  • 미리 알 수 없는 경우 사용 가능하다.

  • 개체가 너무 커서

  • 스택 할당자에 맞지 않는 경우 사용 가능하다.

단점

  • 할당 작업으로 인한 속도 저하

    • 단지 할당하는 데 시간이 많이 소요될 수 있다.


  • 해제 작업으로 인한 속도 저하

    • 주로 병합을 사용할 때

    • 해제 작업에 더 많은 주기가 소요된다.


    • 병합하는 동안

    • 각 해제 작업에서는

    • 해당 인접 항목을 찾아내어 더 큰 블록을 만들고

    • 그 블록을 해제 목록에 다시 삽입한다.

    • 그러한 찾기가 수행되는 동안에는

    • 메모리가 임의의 순서로 액세스되어

    • 캐시 누락이 발생하고

    • 성능이 저하될 수 있다.


  • 힙 손상으로 인한 속도 저하

    • 응용 프로그램에서

    • 힙 블록을 적절하게 사용하지 않을 경우

    • 힙이 손상된다.

    • 가장 많이 발생할 수 있는 힙 손상 문제로는

    • 이중 해제, 해제 후 블록 사용, 블록 경계를 벗어나 덮어쓰기 등이 있다.


  • 힙 경합으로 인한 속도 저하

    • 두 개 이상의 쓰레드에서

    • 동시에 데이터에 액세스하려고 하면

    • 경합이 발생하여

    • 한 쪽 쓰레드의 작업이 완료되어야

    • 다른 쪽 쓰레드의 작업이 진행될 수 있다.


    • 경합으로 인해 항상 문제가 발생하며

    • 이 문제는 현재 다중 프로세서 시스템에서

    • 일어나는 문제 중 가장 큰 문제다.


    • 메모리 블록을 아주 많이 사용하는 응용 프로그램이나

    • DLL이 여러 개의 쓰레드로 실행되거나

    • 다중 프로세서 시스템에서 실행되면 속도가 느려진다.

    • 이 문제를 해결하려면

    • 일반적으로 단일 잠금 방법을 사용하여

    • 해당 힙을 사용하는 모든 작업을 Serialize한다.

    • 이러한 Serialization으로 인해

    • 쓰레드에서는 잠금을 기다리는 동안

    • 컨텍스트를 스위칭 할 수 있다.


    • 경합은 일반적으로

    • 쓰레드와 프로세스의 컨텍스트 스위칭을 가져온다.

    • 컨텍스트 스위칭에도 리소스가 많이 소모되지만

    • 프로세서 캐시에서 데이터가 손실되어

    • 나중에 해당 쓰레드가 다시 살아날 때

    • 이 데이터를 다시 작성하는 데에

    • 리소스가 훨씬 많이 소모된다.

그럼 Heap 영역, 동적 할당은 왜 필요한 것일까?

  • 메모리를

  • 효율적으로 관리할 수 있기 때문이다.


  • 임베디드 시스템을 개발하다보면

  • 하드웨어 크기가 매우 작은 경우가 많다.

  • 하드웨어 크기가 작다는 것은

  • 메모리의 용량도 작음을 의미한다.

  • 그러한 작은 메모리 공간에

  • 프로그래머가 메모리 관리의 달인이라면

  • 컴파일러가 자동으로 할당해주는 것보다

  • 더 효율적인 관리가 가능하다.


  • 물론 메모리 용량이 클 수도 있지만

  • 가격이 매우 비싸질 것이다.


Overflow

Heap overflow

  • Heap이 위에서부터 주소값을 채워져 내려오다가

  • Stack영역을 침범하는 경우

Stack overflow

  • Stack영역이 Heap을 침범하는 경우

  • Stack의 지역변수는 사용되고 소멸하므로

  • 데이터 용량불확실성을 가지므로

  • 밑에서부터 채워 올리고

  • Heap은 위에서부터 채워 내려진다.

  • Stack 영역에서의

  • 주소값

  • 밑에서부터(먼저선언된 순서) 정해지며

  • 그 다음 주소는 순서대로 정해진다.


참고


Similar Posts

Comments