이번 글에서는 링킹에 대해 알아보겠습니다.
링킹의 의미
우선 자바 코드를 컴파일(바이트코드로 변환)한 오브젝트 파일을 실행을 시켜야하는데 오브젝트 파일만으로는 실행시킬 수 없습니다.
그래서 실행시키기위해서 해당 코드에서 필요로 하는 다른 프로그램 혹은 외부 라이브러리들을 가져와 연결하는 과정이 링킹입니다.
(작성한 코드에서 사용한 외부 라이브러리를 알 수 없으면 당연히 정상적으로 실행될 수 없겠지요)
링킹 과정을 거치고 나면 .exe 실행파일이 만들어집니다.
이러한 링킹을 담당하는 프로그램이 링커입니다.
링킹의 종류
이제 링킹의 종류 2가지를 알아봅시다. 정적 링킹(Static Linking)과 동적 링킹(Dynamic Linking)이 있습니다.
정적 링킹
정적 링킹이란 실행 가능한 파일을 만들 때 프로그램에서 사용하는 모든 라이브러리의 모듈을 복사하는 방식입니다.
- 개의 프로그램에서 A라는 외부 함수/라이브러리를 이용한다면, 5개의 프로그램의 실행 파일 각각에 A의 정보가 담기므로 중복이 발생합니다. => 정적 링킹으로 만들어진 프로그램은 크기가 크고 메모리 효율이 좋지 않게 되지요.
- 또한 A라는 외부 함수에 변화가 생기면 변화를 적용하기 위해 재컴파일하여 다시 링킹해야합니다. (A 정보를 그냥 복사해왔기 때문이지요)
- 장점
- 모두 한 실행 파일에 포함되어 있기 때문에 동적 링킹 라이브러리를 사용하는 프로그램보다 빠릅니다.
- 정적 링킹 라이브러리를 사용하는 프로그램에서 필요한 모듈을 모두 복사하여 하나의 실행 파일에 저장하기 때문에 사용하는 곳과 사용되는 곳의 위치가 항상 일치하여 불일치에 대한 걱정을 하지 않아도 됩니다.
동적 링킹
동적 링킹이란 실행 파일을 만들 때 프로그램에서 사용하는 모든 라이브러리의 모듈의 주소만을 가지고 있다가, 런타임에 실행 파일과 라이브러리가 메모리에 위치될 때 해당 모듈의 주소로 가서 필요한 모듈을 연결(링크)하는 방식입니다.
말 그대로 "동적 Dynamic" 링킹은 프로그램이 메모리 공간에 올라가서 실행될 때 (런타임 시점에) 다이나믹하게 링킹됩니다.
- 5개의 프로그램에서 A라는 외부 라이브러리를 이용한다면, A는 메모리에 따로 로드되어 있고, 각각의 파일에서 A의 주소만 가리키면 됩니다. 따라서 정적 링킹 방식에 비해 실행 파일의 크기가 작아서 메모리와 디스크 공간을 더 아낄 수 있습니다.
- 라이브러리가 독립적으로 모듈화되어있기 때문에, 라이브러리에 변경사항이 있을 때에도 실행 파일의 수정없이 라이브러리만을 수정한 후 배포하면 자동으로 프로그램은 수정된 라이브러리를 사용하게 됩니다.
- 즉 그 변화를 적용하기 위해 재컴파일하여 다시 링킹할 필요없이 배포 시에 A의 주소만 따라가면 변화된 A가 있는 것입니다!
- 동적 링킹 방식이 적용된 프로그램은 동적 라이브러리가 메모리에 이미 존재할 경우에 로드되는 시간을 단축할 수 있습니다.
- 단점
- 동적 링킹 방식은 매번 주소를 따라가야하는 오버헤드가 존재하여 느립니다.
- 불일치 문제 고려 : 어떤 프로그램에서 A라는 함수를 동적 링킹 방식으로 사용하고 있지만, 해당 함수가 시스템에서 제거되면 해당 프로그램의 실행가능 파일에서는 A의 주소가 있어서 마치 존재하는 것 같지만 실제 A는 시스템에 더이상 존재하지 않기 때문에 불일치가 발생합니다.
오버헤드 ?
프로그램의 실행흐름에서 특정 기능을 수행하기 위해 소요되는 간접적인 처리 시간 · 메모리, 자원이 사용되는 현상입니다.
예를 들면, 프로그램의 실행흐름 도중에 동떨어진 위치의 코드를 실행시켜야 할 때 추가적으로 시간,메모리,자원이 사용되지요. 이를 오버헤드라 합니다. 만약 기능을 수행하는데 10초가 걸리는 기능이 간접적인 요소들로 20초가 걸린다면 10초의 오버헤드가 존재하는 것입니다.
라이브러리
특정 기능을 수행하는 코드(함수 혹은 클래스)를 포함하는 컴파일된 파일들을 모은 패키지입니다.
소프트웨어 개발 시 공통으로 사용할 수 있는 특정 기능들을 모듈화한 것으로, 저희 개발자들은 이렇게 잘 구현된 함수들을 라이브러리 단위로 import하여 개발하는데에 쉽게 이용할 수 있습니다.
정적 라이브러리(.lib)와 동적 라이브러리(.dll)
정적 라이브러리는 실행 파일과 링크를 걸면, static하게 실행 파일 내에 포함이 되는 라이브러리입니다.
쉽게 말하면 라이브러리를 코드 내에서 import했을 때 컴파일 시점에 소스코드와 결합이 되는 라이브러리입니다.
소스코드를 컴파일을 할 때 링커에 의해 라이브러리 내 실제 사용되는 함수들이 모두 실행하려는 프로그램 소스코드에 포함됩니다.
그렇기 때문에 라이브러리 용량에 따라 실행파일의 크기가 커지게 됩니다.
위의 정적 링킹에서 언급했듯, 실행 속도는 빠르지만 라이브러리에 변화가 있을 시 이 라이브러리를 사용하는 모든 실행 파일은 재컴파일과 새 라이브러리 파일을 링크해야하기 때문에 유연성이 떨어집니다.
동적 라이브러리란 프로그램이 실행(런타임)될 때 실행 파일들과 연결하는 라이브러리입니다.
쉽게 말하면 프로그램 실행시에, 코드 내에서 DLL 내의 함수가 필요할 때만 DLL에 접근하여 사용한 후, 다시 코드로 돌아오는 방식으로 실행됩니다.
따라서 동적 라이브러리 파일은 컴파일 후에도 실행파일과 독립되어있기 때문에, 배포 시에도 DLL 파일의 위치를 실행파일에서 설정한 공간에 위치시켜야 합니다.
마지막으로 제가 말씀드리고 싶은 DLL의 특성은..
동적 라이브러리는 운영체제에 의해 로드되면 물리 메모리에 계속 남아있게되고,
소스코드가 메모리에 올라갈 때 동적 라이브러리가 가지는 가상 메모리 주소와 매핑이 됩니다.
참고
https://www.youtube.com/watch?v=JK6U91t7mgY
https://velog.io/@hjkdw95/%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC%EA%B0%80-%EB%AD%98%EA%B9%8C
: https://live-everyday.tistory.com/69
'Computer Science' 카테고리의 다른 글
[Network] TCP/UDP (0) | 2022.04.25 |
---|---|
[네트워크] 프로토콜과 OSI 계층 (0) | 2022.04.25 |
멀티 프로세스와 멀티 스레드 (feat. 아파치와 톰캣) (0) | 2022.04.18 |
프로세스(Process)와 스레드(Thread) (0) | 2022.03.14 |