1) 개요
- 공유 라이브러리는 여러 라이브러리 함수를 여러 프로세스가 실행 중에 공유할 수 있게
하나로 묶어주는 기술이다.
이 기술을 이용하면 DISK와 RAM의 공간을 절약할 수 있다.
2) 오브젝트 라이브러리
- 프로그램을 만드는 방법 하나는 단순히 소스 파일을 컴파일해서
해당 오브젝트 파일을 만들고,
만들어진 모든 오브젝트 파일을 링크해 실행 가능한 프로그램을 만드는 것이다.
그 예는 다음과 같다.
cc -g -c prog.c mode1.c mod2.c mod3.c
cc -g -o prog_nolib prog.o mod1.o mod2.o mod3.o
- 그러나 여러 프로그램에서 공통으로 사용하는 소스 파일이 여러 개인 상황이 있다.
이런 경우에 수고를 덜 수 있는 첫 번째 방법은 우선 소스 파일을 한 번 컴파일하는 것이다.
그리고 컴파일된 오브젝트 파일을 여러 실행 파일이 요구하는 대로 링크한다.
- 이런 작업은 컴파일 시간을 단축시킬 수 있지만,
링크하는 과정에서 모든 오브젝트 파일을 지정해야 하는 번거로움이 있다.
더욱이 디렉토리가 여러 오브젝트 파일로 복잡해져 불편할 수도 있다.
- 이런 문제를 회피하려면 여러 오브젝트 파일을 라이브러리라는 하나의 단위로 묶는다.
이런 오브젝트 라이브러리에는 정적(static)과 공유(shared)의 두 가지 방식이 있다.
공유 라이브러리는 좀 더 현대화된 형태의 오브젝트 라이브러리이고,
정적 라이브러리에 비해 몇 가지 향상된 기능을 제공한다.
3) 정적 라이브러리
- 공유 라이브러리를 알아보기에 앞서 우선 정적 라이브러리를 살펴보자.
정적 라이브러리를 알아야 공유 라이브러리의 이점과 차이점을 이해하는데 도움이 되기 때문이다.
- 아카이브(archive)라고 알려진 정적 라이브러리는 유닉스 시스템에서 제공한
첫 번째 라이브러리 형태다.
이는 다음과 같은 이점을 제공한다.
(1) 흔히 사용하는 여러 오브젝트 파일을 하나의 라이브러리 파일 형태로 만든다.
이를 사용하는 각 응용 프로그램을 만들 때, 라이브러리의 원본 소스 파일을 재컴파일하지 않고
여러 실행 파일을 만들 수 있다.
(2) 링크 명령을 단순화할 수 있다.
링크할 때 여러 오브젝트 파일을 열거하는 대신,정적 라이브러리 이름만 지정하면 된다.
링커는 필요한 정적 라이브러리를 찾아 적절한 오브젝트를 추출하는 방법을 알고 있기 때문이다.
- 사실 정적 라이브러리는 단순히 라이브러리에 추가된 모든 오브젝트 파일의 복사본이
들어 있는 파일이다.
이 파일에는 오브젝트 파일뿐만 아니라 파일 접근 권한, 유저 ID와 그룹 ID,
마지막으로 수정한 시간 등 각 파일의 다양한 속서이 기록되어 있다.
- 정적 라이브러리 이름은 관례상 libname.a와 같은 형태로 지정된다.
4) 공유 라이브러리 개요
- 프로그램이 정적 라이브러리를 링크해서 만들어지면,
실행 파일에는 프로그램에 링크된 모든 오브젝트 파일이 복사된다.
따라서 몇 개의 실행 파일에 같은 오브젝트 모듈을 사용하는 경우,
각 실행 파일마다 같은 오브젝트 모듈이 복사되어 저장된다.
- 이런 복사된 중복 모듈에는 다음과 같은 단점이 있다.
(1) 같은 오브젝트 모듈이 복사되어 저장되므로 디스크 공간이 (매우 많이) 낭비된다.
(2) 일부 다른 프로그램이 같은 모듈을 사용하고 동시에 실행된다면,
오브젝트 모듈의 각 복사본이 다른 가상 메모리 공간을 차지하므로,
시스템의 전체 메모리 사용량을 증가시킨다.
(3) 정적 라이브러리상의 오브젝트 모듈을 수정해야 한다면,
그 모듈을 사용하는 모든 실행 파일에 변경된 코드를 반영하려면
전부 새로 링크해야 한다.
이는 시스템 관리자가 어떤 응용 프로그램이 어느 라이브러리에 링크되어 있는지
알고 있어야 한다는 더욱 복잡한 문제를 야기한다.
- 공유 라이브러리는 이와 같은 단점을 극복하고자 설계됐다.
공유 라이브러리의 핵심 아이디어는 단 하나의 오브젝트 모듈을
모든 프로그램에서 공유하게 하는 데 있다.
- 오브젝트 모듈은 링크된 실행 파일에 복사되지 않는다.
대신, 모듈을 처음 사용하는 프로그램이 실행될 때, 메모리에 적재된다.
같은 공유 라이브러리를 사용하는 프로그램이 후에 실행됐을 때는
이미 메모리에 적재된 모듈을 사용한다.
- 공유 라이브러리를 사용하면 실행 프로그램이 디스크 공간과
(실행 중에) 가상 메모리를 덜 사용한다.
5) 공유 라이브러리 장점과 단점
- 공유 라이브러리의 장점은 다음과 같다.
(1) 전체적인 프로그램 크기가 작아지기 때문에,
어떤 경우에는 프로그램이 메모리에 이미 적재되어 있을 수 있으므로
더 빨리 실행이 가능하다.
하지만 거대한 공유 라이브러리가 다른 프로그램에 의해
메모리에 이미 적재되어 있는 경우에만 해당되는 사항이다.
보통 처음 시작하는 프로그램은 공유 라이브러리를 메모리상에서 찾아야 하고,
이를 메모리에 적재해야 하기 때문에 실행되기까지 좀 더 많은 시간이 소요된다.
(2) 오브젝트 모듈이 실행 파일에 복사되지 않고 대신에 중앙에서 관리되기 때문에
오브젝트 모듈을 수정해야 하는 경우
모든 응용 프로그램의 수정사항을 반영하려고 재링크할 필요가 없다.
심지어 실행 중인 프로그램이 기존 버전의 공유 라이브러리를 사용하는 경우에도
수정이 가능하다.
- 추가된 기능 때문에 발생하는 비용은 다음과 같다.
(1) 공유 라이브러리는 개념적으로 복잡할 뿐만 아니라
실제 공유 라이브러리를 생성하고 프로그램을 만드는 과정이
정적 라이브러리에 비해 복잡하다.
(2) 공유 라이브러리는 위치 독립적인 코드를 사용해 컴파일해야 한다.
하지만 이런 작업은 추가로 레지스터를 사용해야 하기 때문에
대부분 시스템 구조에 성능 부하를 준다.
(3) 실행 시점에 심볼 재배치(symbol relocation)을 반드시 수행해야 한다.
심볼을 재배치하는 동안 공유 라이브러리 상의 심볼을 가리키는 참조는
가상 메모리상의 실제 실행 시 위치로 수정된다.
이런 재배치 프로세스 때문에 공유 라이브러리를 사용하는 프로그램은
정적 라이브러리를 사용하는 프로그램보다 실행하는데 더 오래 걸릴 수 있다.
'CS Fundamental' 카테고리의 다른 글
[CS Fundamental] 인텔 x86 구조 및 ARM의 발전 과정 (0) | 2025.01.14 |
---|---|
[CS Fundamental] 아스키 코드 (0) | 2025.01.14 |
[CS Fundamental] 단순 전자우편 전송 프로토콜(SMTP)이란? (0) | 2025.01.14 |
[CS Fundamental] C 또는 C++에서 메모리 관련 버그에는 어떤 것이 있는가? 각각 디버깅은 어떻게 할 수 있는가? 자바 또는 다른 언어에서의 garbage collecter의 역할은 무엇이고 그 원리는 무엇인가? (0) | 2025.01.10 |
[CS Fundamental] PNG 포맷에서 투명을 어떻게 표현하나요? (0) | 2025.01.10 |