2021년 08월 29일 TIL
오늘은 공부를 하다가 동적 라이브러리와 정적 라이브러리의 차이를 묻는 글을 보았고, 그것을 몰랐기에 공부해보려고 했다.
라이브러리 확장자
-
OS별 확장자
-
*.a
리눅스 / 정적 라이브러리
-
*.so
리눅스 / 동적 라이브러리
-
*.lib
윈도우 / 정적 라이브러리
-
*.dll
윈도우 / 동적 라이브러리
-
###
라이브러리란
소프트웨어를 만들 때 쓰이는 클래스나 서브루틴들의 모임을 가리키는 말이다.
소프트웨어 개발할 때 컴퓨터 프로그램이 사용하는 비휘발성 자원의 모임
공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것.
표준 라이브러리 / 런타임 라이브러리
표준 - 특정한 언어의 개발 환경에 기본적으로 포함된 것. 기본적인 기능 수행과 더불어 디버깅, 성능 측정 등을 위한 별도의 API가 존재한다.
런타임 - 프로그램이 실제 환경에서 실행되기 위해 필요한 모듈들이다. 대부분 위의 표준 라이브러리에서 기능 수행에 필요한 것들만 제공되거나 스크립트의 실행기 등을 말한다.
동적 라이브러리(Shared Library)와 정적 라이브러리 차이
-
동적 라이브러리
완성된 프로그램을 실행할 때 포함시키는 동적 라이브러리
-
정적 라이브러리
프로그램을 컴파일하는 과정에서 포함시키는 오브젝트 파일들의 모임
동적 라이브러리
- DLL을 구현하고 컴파일하고 나면 Static library와는 다르게 Output file이 2개 생성된다.
- 하나는 *.lib 파일이고 하나는 *.dll 파일이다.
- lib 파일은 암시적 링킹시 필요, dll은 실행 시 필
- 여기서 *.lib 파일은 Static library의 *.lib 파일과는 전혀 다르다.
- Static library의 *.lib 파일은 라이브러리 전체 코드를 포함하는 바이너리이며, DLL의 *.lib 파일은 DLL이 제공하고자 하는 함수 정보를 갖는 정보 파일이다.
- 프로그램이 시작할 때 같이 로딩되어 프로그램 종료할 때 메모리에서 해제되는 방법을 암시적 링킹(Implicit Linking)이라 한다.
- 정적 라이브러리는 프로그램 빌드 시에 라이브러리가 제공하는 코드를 실행 파일에 넣는 방식의 라이브러리
- DLL의 *.lib 파일을 이용하여 링킹하는 것을 암시적 링킹(Implicit Linking)이라 한다.
- 프로그램 실행 시 필요시만 외부 DLL 파일에서 함수를 참조한다.
- 실행 바이너리를 링크 단계에서 실행 바이너리의 obj 파일들과 dll의 lib 파일을 함께 링크해서 이 정보를 토대로 runtime에 dll의 함수 코드를 참조하게 된다.
장점
- 메모리 절약, 스와핑 감소
- 프로그램이 한번 메모리에 올려진 것을 공유하므로 메모리 사용 공간이 정적 라이브러리에 비해 적다.
- 여러 프로세스가 메모리에 있는 하나의 DLL 복사본을 공유하여 하나의 DLL을 동시에 사용 가능
- 정적 연결 라이브러리를 사용하여 빌드된 응용 프로그램의 경우 Windows는 각 응용 프로그램에 대해 하나의 라이브러리 코드 복사본을 메모리에 로드해야 한다.
- 동적은 메모리에 올라와있는 DLL을 참조하여 사용하기 때문에 1개만 있으면 되지만 정적은 빌드 시 라이브러리를 함께 컴파일이 이뤄져야하기 때문에 각 프로그램마다 라이브러리 코드를 갖고있는다.
- DLL을 보다 쉽게 업그레이드 할 수 있다.
- DLL의 함수가 변경되어도 이 함수의 인수 및 반환 값이 변경되지 않았으면 그 함수를 사용하는 응용 프로그램은 다시 컴파일하거나 링크할 필요가 없다.
- 반면, 정적으로 링크되는 개체 코드의 경우에는 함수가 변경되면 응용 프로그램을 다시 링크시켜야 한다.
- 출시 후 지원이 가능하다. 예를 들어, 응용 프로그램을 출시할 때 사용할 수 없었던 디스플레이 기능을 지원하도록 디스플레이 드라이버 DLL을 수정할 수 있다.
- 언어 형식이 다른 여러 프로그램을 지원한다.
- 서로 다른 프로그래밍 언어로 작성된 프로그램인 경우에도 함수의 호출 규칙을 따르기만 하면 여러 프로그램에서 동일한 DLL 함수를 호출 할 수 있다.
- 이 경우 각 프로그램과 DLL 함수는 여러 가지 면(스택에 해당 함수의 인수가 들어가는 순서, 스택을 정리하는 것이 함수인지 응용 프로그램인지의 여부 및 인수가 레지스터에 전달되는지의 여부)에서 호환 될 수 있어야 한다.
- 프로그램 변경시 변경된 부분의 공유 라이브러리만 재배포하면 되므로 유지보수가 쉽다.
단점
- 외부 의존도가 생기기 때문에 이식성이 어렵다.
- 공유 라이브러리를 메모리에 올리려면 찾고 올리는데 시간이 걸리므로 성능저하가 생긴다.
정적 라이브러리(Static Libray)
- 프로그램 빌드 시에 라이브러리가 제공하는 코드를 실행 파일에 넣는 방식의 라이브러리를 의미한다.
- 컴파일의 링킹 단계에서 실행 파일에 결합된다.
- 특정 기능의 라이브러리를 static 하게 제작한다는 것은 컴파일의 link 단계에서 라이브러리(*.lib 파일)를 실행 바이너리에 포함시킨다는 얘기이다.
- 즉 라이브러리의 동작 코드가 이를 사용하는 실행 바이너리 속에 포함되기 때문에 별도의 추가 작업없이, 그리고 독립적으로 라이브러리 함수들을 사용할 수 있다.
- 정적 라이브러리를 사용하여 컴파일을 하면 링커가 프로그램이 필요로 하는 부분을 라이브러리에서 찾아 실행파일에 바로 복사한다.
- 실행 파일에 다 들어가기 때문에 실행 시 라이브러리가 필요없다.
장점
- 시스템 환경이 변해도 애플리케이션에 아무런 영향이 없고, 완성된 애플리케이션을 안정적으로 사용할 수 있다.
- 컴파일시 필요한 라이브러리를 프로그램 내에 적재하기 때문에 이식성이 좋다.
- 런타임시 외부를 참조할 필요가 없기 때문에 속도에서 장점이 있다.
단점
- 같은 코드를 가진 여러 프로그램을 실행할 경우 코드가 중복이 되니 그만큼 메모리를 낭비하게 된다.
- 라이브러리 변경이 필요할 시, 변경된 라이브러리만 재배포하면 안되고 프로그램을 다시 재배포 해야 한다.