Some Terminologies
- Dynamic Loading
- Dynamic Linking
- Overlays
- Swapping
● 동적 로딩 (Dynamic Loading)
프로그램 전체를 메모리에 올리는 것이 아니라 필요할 때(해당 루틴이 불려질 때마다) 해당 루틴을 메모리에 올리는 것이다.
프로그램은 방어적으로 만들어지기 때문에 프로그램 전체가 균일하게 사용되는 게 아니다.
프로그램 중에서 상당 부분은 거의 사용되지 않는 오류 처리 루틴이 많으며 주로 사용되는 부분은 한정적이다.
좋은 프로그램일수록 오류 루틴이 많다. 그래서 미리 올려놓는 게 아니라 오류가 생기면 그때 메모리에 올리는 것과 같은 방식을 Dynamic Loading이라고 한다.
프로그램을 실행시키면 통째로 메모리에 올라가지 않고 당장 필요한 부분만 메모리에 올리고 필요 없으면 디스크로 쫓아낸다.
이건 원래 Original Dynamic Loading은 아니고 운영체제가 관리해 주는 Paging System에 의해 이루어진다.
Paging 기법에서 메모리에 올라가고 내려가고 하는 것은 운영체제가 직접 관리해 주는 것이고 보통 Dynamic Loading이라고 하면 운영체제가 지원해 주는 게 아니라 프로그래머가 Dynamic Loading을 직접 하도록 하는 개념이다.
프로그래머가 수작업으로 언제 어디다가 올리고 하는 걸 작성하는 건 아니고, Dynamic Loading을 쉽게 하도록 운영체제가 라이브러리 형태로 제공을 해준다.
현재 시스템에서 이루어지는 Paging 기법과 Dynamic Loading은 원래 다르다. 그런데 지금은 섞어서 사용하기는 한다.
프로그래머가 명시적으로 Dynamic Loading을 해서 이루어지는 게 원래 Dynamic Loading이다. 프로그래머가 명시하지 않고 운영체제가 하는 건 Paging이라고 부른다.
✓ 프로세스 전체를 메모리에 미리 다 올리는 것이 아니라 해당 루틴이 불려질 때 메모리에 load 하는 것
✓ Memory Utilization의 향상
✓ 가끔씩 사용되는 많은 양의 코드의 경우 유용 : Ex) 오류 처리 루틴
✓ 운영체제의 특별한 지원 없이 프로그램 자체에서 구현 가능 (OS는 라이브러리를 통해 지원 가능)
● 동적 링킹 (Dynamic Linking)
프로그램을 작성한 다음에 컴파일한 후, 링크해서 실행 파일을 만든다.
링크라는 것은 여러 군데에 존재하던 컴파일된 파일들을 묶어서 하나의 실행 파일로 만드는 것이다.
프로그래머가 소스파일을 여러 개 따로 코딩을 해서 링킹을 하기도 하고 직접 작성하지 않은 유용한 라이브러리도 링킹이 되어서 실행 파일이 만들어진다.
라이브러리가 실행 파일 코드에 이미 포함이 되어있으면 Static Linking이다.
Dynamic Linking은 라이브러리 코드가 내 실행 파일 코드에 포함이 되지 않는다.
프로그램이 실행되다가 라이브러리를 호출하는 코드에 도달하면 그 라이브러리가 어디에 존재하는지 찾는다.
실행 파일에는 이 라이브러리의 위치를 알 수 있는 포인터만 실행 파일에 두며, 보통 별도의 파일 형태로 라이브러리가 존재한다.
필요하면 메모리에 올리고 이미 올라와 있으면 해당 주소로 가서 실행한다.
예를 들어, 내가 프로그램을 만들면서 printf라는 라이브러리 함수를 사용한다고 해보자.
이 라이브러리가 Static Linking이면 내가 만든 실행 파일 안에 printf의 코드가 이미 포함이 되어있는 것으로 내 프로그램 주소 공간 안에서 그냥 실행이 된다.
프로그램 100개에 printf가 있고, 그 100개의 print문을 실행시키게 되면 printf라는 같은 기능을 하는 코드라 하더라도 그 코드가 100 copy가 다 올라가게 될 것이다
Dynamic Linking은 printf가 내 실행 파일에 들어가지 않고 printf가 실행되는 라이브러리가 어디에 있는지 위치를 찾는 코드만 내 프로그램 안에 집어넣는다.
그렇게 되면 프로그램을 실행할 때 printf를 호출하는 위치에 도달했을 때 printf에 해당하는 라이브러리 파일을 찾아 메모리에 올려서 실행한다.
이미 메모리에 올라와 있다면 해당 메모리를 공유해서 사용할 수 있다.
Dynamic Linking을 해주는 라이브러리를 Shared Library라고도 하며, 리눅스에서는 Shared Object, 윈도우에서는 DLL (Dynamic Linking Library)라고 한다.
✓ Linking을 실행 시간(Execution time)까지 미루는 기법
✓ Static Linking
- 라이브러리가 프로그램의 실행 파일 코드에 포함 됨
- 실행 파일의 크기가 커짐
- 동일한 라이브러리를 각각의 프로세스가 메모리에 올리므로 메모리 낭비 (eg. printf 함수의 라이브러리 코드)
✓ Dynamic Linking
- 라이브러리가 실행시 연결(Link)됨
- 라이브러리 호출 부분에 루틴의 위치를 찾기 위한 stub이라는 작은 코드를 둠
- 라이브러리가 이미 메모리에 있으면 그 루틴의 주소로 가고 없으면 디스크에서 읽어옴
- 운영체제의 도움이 필요
● Overlays
- 메모리에 프로세스의 부분 중 실제 필요한 정보만을 올림
- 프로세스의 크기가 메모리보다 클 때 유용
- 운영체제의 지원없이 사용자에 의해 구현
- 작은 공간의 메모리를 사용하던 초창기 시스템에서 수작업으로 프로그래머가 구현 : "Manual Overlay", 프로그래밍이 매우 복잡
● Swapping
Swapping은 프로세스가 메모리에서 하드 디스크로 쫓겨났거나 다시 올라오거나 하는 과정이다.
메모리에서 쫓겨난 후에 저장하는 곳을 Backing Store (Swap Area)라고 한다.
Backing Store로 쫓겨나는 건 Swap Out이라고 하고, 반대로 쫓겨났다가 다시 올라오는 것은 Swap In이라고 부른다.
중기 스케줄러가 바로 Swap Out 시킬 프로그램을 정하는 것이다.
메모리에 너무 많은 프로그램이 올라가 있으면 중기 스케줄러가 일부 프로그램을 통째로 디스크로 쫓아내는 일을 한다.
CPU 우선순위가 낮은 프로그램을 쫓아내는 것이 효율적이다.
Swapping 시스템이 지원되기 위해서는 앞에서 살펴봤던 주소 Binding 하고 연결해서 생각해야 한다.
만약 Compile Time Binding이나 Load Time Binding이 사용되고 있으면 Swapping 해서 메모리에서 쫓겨났다가 다시 올라올 때 원래 위치로 올라와야 한다.
이 말은 즉, 다른 메모리 영역이 비어있다 하더라도 반드시 원래의 번지로 올라가야 하기 때문에 Swapping 효과를 발휘하기 어렵다.
Swapping이 좀 더 효율적으로 동작하려면 Run Time BInding이 지원되어야 한다.
300번지에 엤던 프로그램이 Swap Out 되어 디스크로 내려갔다가 다시 메모리로 올라올 때 다른 주소로 올라올 수 있어야 한다.
메모리에서 프로그램을 통째로 쫓아냈다가 다시 올라오게 하는 일은 File 입출력과는 다르게 양이 많다.
File 입출력에서는 디스크 헤드가 이동하는 시간인 Seek Time이 대부분을 차지하며 데이터를 전송하는 Transfer Time은 굉장히 미미하다.
하지만 용량이 매우 큰 Swapping 시스템에서는 Seek Time도 중요하지만 양이 많기 때문에 Transfer Time도 상당 부분을 차지한다.
최근에는 Paging 시스템에서 프로그램 전체가 쫓겨나는 게 아니라 프로그램 주소 공간이 잘게 잘려서 일부 페이지가 메모리에서 쫓겨나는 것 마저도 Swap Out 되었다는 표현을 쓰기는 한다. Swap Out은 원칙적으로는 프로그램 전체가 쫓겨나는 것을 의미한다.
✓ Swapping : 프로세스를 일시적으로 메모리에서 Backing Store로 쫓아내는 것
✓ Backing Store (Swap Area) : Disk. 많은 사용자의 프로세스 이미지를 담을 만큼 충분히 빠르고 큰 저장 공간
✓ Swap in / Swap out : 일반적으로 중기 스케줄러(swapper)에 의해 swap out 시킬 프로세스 선정
✓ priority-based CPU scheduling algorithm
- Priority가 낮은 프로세스를 swapped out 시키고 Priority가 높은 프로세스를 메모리에 올려 놓음
- Compile time 혹은 load time binding에서는 원래 메모리 위치로 swap in 해야 함
- Execution time binding에서는 추후 빈 메모리 영역 아무 곳에나 올릴 수 있음
- swap time은 대부분 transfer time (swap되는 양에 비례하는 시간)임
다음 포스팅에서는 이 물리적 메모리를 어떻게 관리할 것인가에 대해 정리를 해볼 것이다.