본문 바로가기

별걸다하는 IT/운영체제 OS

[운영체제]Static Linking vs Dynamic Linking(shared Library) 정적링킹 vs 동적링킹

반응형

운영체제 목차

 

Dynamic Linking을 이해하려면 Linking에 대해 이해를 하고 있어야하기 때문에 저번시간에 링킹에 대해서 포스팅을 했어요

 

링킹과정에서 오브젝트 파일을 라이브러리와 같이 Linking을 하는데 그 Linking을 하는 방법에 크게 두 가지가 있어요 

딱 감이오죠 ? Dynamic Linking과 Static Linking!

 

Static Linking이란?

일단 Static Linking이 이해하기 쉬운데 실행파일 만들 때 라이브러리를 같이 포함시켜서 .exe파일을 만드는 것을 Static Linking 즉 정적링킹이라고 합니다. 

 

예를 들어 출력할 때 cout이라는 클래스 라이브러리를 사용하잖아요 그 cout이라는 클래스 라이브러리를 실행하는 코드가 있겠죠. hello.exe에다가 집어넣어서 만든 것이 Static Linking입니다.

 

위키백과는 이렇게 정의하고 있네요 

정적 라이브러리는 루틴들과 외부 함수들 그리고 변수들의 집합으로서, 컴파일 타임에 호출자에 의해 리졸브되며 컴파일러와 링커에 의해 목적 파일과 독립된 실행 파일을 생성하기 위해 대상 애플리케이션에 복사된다.

 

그럼 정적 라이브러리를 실행파일에 추가시켜서 사용하는 정적링킹이의 단점이 무엇이길래 동적 링킹이라는 개념이 생겨났을까요?

 

정적링킹의 단점

 

정적 라이브러리를 사용하여 컴파일을 하면 링커가 프로그램이 필요로 하는 부분을 라이브러리에서 찾아 실행파일에다가 바로 복사합니다. 실행파일에 다 들어가기 때문에 라이브러리가 필요 없어요. 미리 컴파일 되어 있기 때문에 컴파일 시간도 단축됩니다. 또 직접 구현한 코드를 라이브러리화시켜서 기술 유출 방지로 사용할 수도 있어요.

 

하지만 실행 파일 내에 라이브러리 코드가 저장되기 때문에 메모리를 어마어마하게 잡아먹어요 

 

예를 들어, 멀티유저시스템인 LINUX, UNIX 운영체제의 경우에는 사태가 좀 더 심각(?)해집니다.

60명의 유저가 LINUX, UNIX서버에 접속해가지고 동시에 Hell world를 출력시키는 프로그램을 실행시킨다고 가정해봅시다.

리눅스 유닉스에서는 실행파일이 hello니까 (hello.exe가 아님) hello라는 프로그램을 실행시켰는데 얘가 정적링킹으로 만들어진 실행파일이예요

즉 여기서 출력하는데 사용된 cout이라는 클래스 라이브러리가 정적으로 링킹되어 있다는 것은 hello라는 실행파일에 cout클래스 라이브러리 코드가 다 들어가있다는 거죠. 즉 hello를 동시에 60명이 실행시키면 메모리에 cout 정보 코드만 60개가 존재하는거예요.. ㄷㄷㄷ  메모리가 매우 비효율적이죠? 그래서 만든 방법이 Dynamic Linking입니다. 

 

Dynamic Linking 동적링킹이란?

 

자 그럼 동적링킹은 뭐냐!

static linking을 써서 했더니 메모리에 쓸데없이 똑같은게 너무 많이 올라가더라 (static 단점에서 예를 들은 상황처럼!)

그래서 이 cout과 같이 많이 쓰이는 라이브러리는 메모리에 하나만 올리자

그리고 이 프로그램이 cout을 호출할 때 메모리에 있는 cout으로 점프해 그쪽으로 간 후 실행한 다음에 다시 돌아오게 하자!

이것이 Dynamic Linking입니다.

 

그래서 지금 현재 Linux, Unix에서는 프로그램을 개발할 때 별다른 옵션을 주지 않으면 Linking을 동적링킹으로 합니다.

Windows에서도 별다른 옵션을 주지 않으면 동적링킹을 해요 

 

동적 링크 라이브러리를 DLL (Dynamic-link Library)라고 합니다. 즉 윈도우에서 동적링킹할 때 사용되는 라이브러리 파일이예요.

그래서 DLL파일들이 보통 windows 시스템 디렉토리에 있어요. 

 

 

내가 hello world를 C++라이브러리랑 같이 링킹을 해서 실행을 했는데 메모리에 DLL파일이 없어, 그럼 실행을 못하니까 운영체제가 메모리에 DLL파일을 load시켜줍니다. 이렇게 메모리에 한 번 올라가면 그 다음부터는 이 올라가있는 DLL이 수행이 되는거예요 (즉 메모리에 cout이 60개가 잡히는 게 아니라 그림처럼 shared libraries 한 개만 잡히는거죠! )

 

따라서

Dynamic linked libraries are system libraries that are linked to user programs when the programs are run.

= Linking postponed until execution time

- 동적 라이브러리는 프로그램이 실행될 때 링크됩니다.

 

앞에 간단하게 설명 한 것을 좀 더 자세히 풀어쓰자면

With Dynamic Linking, a stub is included in the image for each library-routine reference. The stub is a small piece of code that indicates how to locate the appropriate memory-resident library routine or how to load the library if whether the needed routine is not already present. Stub replaces itself with the address of the routine, and executes the routine.

stub는 라이브러리가 메모리에 존재하지 않을 때, 라이브러리가 메모리에 상주할 수 있도록 라이브러리 루틴을 적절히 적재하는 방법을 알려주는 작은 코드 조각이예요. 

스텁은 모든 라이브러리 루틴에 들어있는데, A라이브러리의 a루틴이 호출되면 stub가 루틴 주소로 대체 돼, 다음에 그 코드가 한 번 더 수행될 때는 Dynamic linking없이 바로 주소를 참조해 실행할 수 있게 되는거예요.

다시 말해, 런타임시 해당 루틴이 불리면 그 스텁은 자신을 그 루틴이 들어있는 주소값과 바꿔치기 해버립니다. 한 번 루틴이 불리게 되면 스텁이 있었다는 사실은 사라지고 주소가 되어 한몸이 되는거죠. 여깄는 단 한 개의 원본을 사용하게 해줘서 메모리 절감 효과를 일으키는거예요.

즉 코드가 중복돼서 적재되지 않는다!

 

동적라이브러리를 윈도우에서는 DLL이라 부르고 Linux와 Unix에서는 dynamic linking library라 안부르고 Shared Library라고 합니다. 리눅스와 유닉스는 Shared Library라고 부르기 때문에 .so라고 쓰거나 .sa라고 씁니다. 그래서 그림이 *.so인거!

 

글 하나하나에 도움이 될 수 있도록 정성을 쏟았어요. 앞으로도 믿을 수 있는 좋은 정보 공유할 수 있는 블로거가 될게요. 비록 비영리 목적의 글이지만 글이 도움이 되신 분들은 광고 한번 클릭해주시면 포스팅을 작성하는 데 비글견처럼 힘이 넘칠 것 같습니다!!
 

동적 링킹의 단점

메모리의 요구사항이 훨씬 적어요. 정적 링킹의 경우 라이브러리 정보를 실행 프로그램당 메모리에 하나씩 다 올리지만 동적 링킹의 경우 동시에 유저가 프로그램을 몇 개를 실행시키던 한 개만 딱 올라가니까요.

 

동적링킹은 내 프로그램 영역에서 라이브러리가 저장되어 있는 주소로 점프하는 거잖아요 

이거는 먼 대로 점프하니까 성능상에서 당연히 약간의 overhead가 들겠죠.

 

또 Dynamic linking을 위한 불필요한 코드가 추가될거예요. 점프해야하니까!

성능상에서는 정적 링킹이 좋지만 메모리 관리차원에서는 동적 링킹이 좋습니다.

 

Shared Library 또는 dynamic library의 또 다른 장점은 여러분들이 실제 느껴봤을 텐데 

게임 프로그램을 만들 때 사용하는 많은 라이브러리가, 예를 들면 direct X라는 게임 library가 있어요

그 라이브러리를 사용한 게임을 내가  주고 샀어. 그런데 게임에 성능이 업그레이드가 되면 게임을 다시 사야 하잖아요

게임이 direct X 만들었는데 direct X라는 library 버전 up 되었어, 그럼 옛날에 내가 게임이 static linking이였다면 새로 버전업 direct X 새로 컴파일을 해서 새로 받거나 새로 사야 하죠. 

그런데 여러분 게임 업그레이드 할 때마다 새로 사나요? 아니죠? 그냥 업데이트 할뿐이잖아요 이게 바로 동적링킹 덕분입니다.

 

이게 만약 dynamic linking으로 direct X 만들어졌다면 

프로그램은 그대로 있지만 direct X 성능이 버전up 돼서 좋아졌으면 dynamic linking library 바꿈으로써 프로그램 성능능을 버전 UP시킬 수 있습니다. 동적 링킹은 이런 장점이 있어요 

 

Dynamic libraries are stored and versioned separately (DLL파일은 따로 저장돼요) 

원래 코드와 라이브러리가 별도로 있는거니까 블랙코드는 그대로 있고 library 버전업이 되면 그거에 대한 성능을 내가 그대로 받을 있다 거죠

 

 

동적링킹 여러분들이 알아야 하는거예요. 연습으로~ 여러분들이 집에서(이미 집인감..ㅎㅎ) 가장 쉬운 hello world cout 만들어 놓고 이걸 static linking으로 컴파일 했을때 나오는 .exe 디폴트인 dynamic linking으로 컴파일 했을 나오는 .exe 크기를 비교해보세요. 당연히 dynamic linking .exe파일의 크기가 엄청나게 작습니다.

 

현재는 정적라이브러리 동적라이브러리 둘다 섞어서 사용합니다.

여기서 정적링킹과 동적링킹 내용은 끝~~


공감과 댓글은 힘이됩니다 :)

 

 

 

반응형