맨위로가기

동적 적재

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

동적 적재는 프로그램 실행 중에 라이브러리나 모듈을 로드하는 기술이다. 이는 IBM의 OS/360에서 처음 사용되었으며, I/O 서브루틴, COBOL, PL/I 런타임 라이브러리에 적용되었다. 주요 장점으로는 하위 시스템 수정 사항의 즉각적인 적용과 라이브러리의 무단 수정 방지가 있다. CICS와 같은 시스템에서 광범위하게 사용되었으며, 현대 운영체제에서 플러그인 구현 및 라이브러리 활용에 중요한 역할을 한다. C/C++에서는 유닉스 계열 운영체제와 윈도우에서 API를 통해 지원되며, 자바에서는 ClassLoader 객체를 통해 클래스를 동적으로 로드할 수 있다. 반면, Plan 9와 9front, 초기 Go 언어는 동적 연결을 지원하지 않았다.

더 읽어볼만한 페이지

  • 라이브러리 - 바이너리 재컴파일러
  • 라이브러리 - 동적 링크 라이브러리
    동적 링크 라이브러리(DLL)는 윈도우 운영체제에서 프로그램 실행 시 필요한 코드와 데이터를 제공하며, 여러 프로그램에서 공유되어 메모리 효율성을 높이고 모듈성을 향상시키는 라이브러리 형식이다.
  • 운영체제 기술 - 프로세스
    프로세스는 컴퓨터에서 실행되는 프로그램의 인스턴스로, 운영 체제가 시스템 자원을 효율적으로 관리하며 멀티태스킹 환경에서 독립적인 실행 흐름을 유지한다.
  • 운영체제 기술 - 커널 (컴퓨팅)
    커널은 운영 체제의 핵심으로, 하드웨어와 소프트웨어 간 상호 작용을 관리하며 시스템 보안, 자원 관리, 하드웨어 추상화, 프로세스 스케줄링, 프로세스 간 통신, 다중 작업 환경 지원 등의 기능을 제공하고, 모놀리식, 마이크로, 혼합형 커널 등으로 구현되며 가상화 및 클라우드 컴퓨팅 환경에서 중요성이 커지고 있다.
동적 적재
설명
동적 적재실행 시간 동안 프로그램에 모듈을 적재하는 메커니즘
개요
특징실행 시간 동안 모듈 적재 가능
필요할 때만 모듈 적재 가능
프로그램 크기 감소
유연성 증가
구현
방법운영체제 API 사용 (LoadLibrary, dlopen 등)
프로그래밍 언어 기능 활용
사용 사례플러그인 시스템
모듈식 소프트웨어 설계
기능 확장
장단점
장점프로그램 크기 감소
유연성 증가
메모리 효율성 증가
유지보수 용이성 증가
단점복잡성 증가
의존성 관리 필요
보안 문제 발생 가능성 증가
같이 보기
관련 개념동적 연결 라이브러리
플러그인
모듈

2. 역사

IBM의 System/360용 운영 체제인 OS/360에서 동적 적재가 처음 사용되었다. 특히 I/O 서브루틴과 COBOL, PL/I 런타임 라이브러리에서 흔히 사용되었으며, z/Architecture용 IBM 운영 체제인 z/OS에서도 계속 사용되고 있다. 응용 프로그램 프로그래머 입장에서 로딩은 운영 체제(또는 I/O 하위 시스템)에 의해 처리되므로 상당히 투명하다. 주요 장점은 다음과 같다.


  • 하위 시스템 수정(패치) 시 프로그램을 다시 링크할 필요 없이 모든 프로그램을 한 번에 수정할 수 있다.
  • 라이브러리를 무단 수정으로부터 보호할 수 있다.


1970년대 이후 IBM의 전략적 트랜잭션 처리 시스템인 CICS는 커널과 일반 응용 프로그램 로딩에 동적 로딩을 광범위하게 사용한다. 응용 프로그램 수정은 오프라인에서 수행 가능하며, 변경된 프로그램의 새 사본은 CICS를 다시 시작할 필요 없이 동적으로 로드할 수 있다. CICS는 24/7로 실행될 수 있으며, 실제로도 자주 그렇게 운영된다.

1980년대에 공유 라이브러리가 유닉스에 추가되었지만, 초기에는 프로그램 시작 후 추가 라이브러리를 로드하는 기능은 없었다.

3. 활용

동적 적재는 소프트웨어 플러그인 구현에 가장 자주 사용된다. 예를 들어, 아파치 웹 서버의 *.dso "동적 공유 객체" 플러그인 파일은 런타임에 동적 적재를 통해 로드되는 라이브러리이다. 동적 적재는 여러 개의 서로 다른 라이브러리가 필요한 기능을 제공하고 사용자가 어떤 라이브러리를 제공할지 선택할 수 있는 컴퓨터 프로그램을 구현하는 데에도 사용된다.

4. C/C++

C/C++에서 동적 적재는 운영체제별 API를 통해 지원된다. 모든 시스템이 동적 적재를 지원하는 것은 아니다. macOS, 리눅스, 솔라리스와 같은 유닉스 계열 운영 체제는 C 언어 "dl" 라이브러리를 통해, 윈도우 운영 체제는 윈도우 API를 통해 동적 적재를 제공한다. 구체적인 API 호출 방식은 '요약' 섹션의 표를 참고하라.

4. 1. 요약

LoadLibraryEx내용 추출dlsymGetProcAddress라이브러리 언로딩dlcloseFreeLibrary


4. 2. 라이브러리 로딩

유닉스 계열 운영체제 (솔라리스, 리눅스, *BSD 등)와 macOS에서는 `dlopen` 함수를 사용하여 라이브러리를 로드한다. macOS에서는 Objective-C의 `NSBundle` 클래스를 사용할 수도 있다. 윈도우에서는 `LoadLibrary` 또는 `LoadLibraryEx` 함수를 사용한다.

운영체제함수
유닉스 계열 (솔라리스, 리눅스, *BSD 등), macOSdlopen
macOSObjective-C의 `NSBundle` 클래스
윈도우LoadLibrary, LoadLibraryEx


4. 3. 라이브러리 내용 추출

유닉스 계열 운영체제에서는 `dlsym` 함수를, 윈도우에서는 `GetProcAddress` 함수를 사용하여 동적 라이브러리의 내용을 추출한다.

운영체제함수
유닉스 계열dlsym
윈도우GetProcAddress


4. 4. 함수 포인터 변환

`dlsym()` 또는 `GetProcAddress()` 함수의 결과는 사용하기 전에 적절한 유형의 포인터로 변환해야 한다. 윈도우에서는 `FARPROC` 타입이 사용된다. 유닉스(POSIX)에서는 `void*`를 함수 포인터로 변환하는 방법에 대한 논의가 있었으며, POSIX 준수를 위해 함수 포인터를 `void*`로 변환할 수 있어야 한다. 타입 펀닝(type punning)을 활용한 해결 방법이 제시되기도 한다.

4. 5. 라이브러리 언로딩

표준 POSIX/UNIX API에서는 `dlclose` 함수를, 마이크로소프트 윈도우 API에서는 `FreeLibrary` 함수를 사용하여 라이브러리 로드를 해제한다. 라이브러리를 로드하면 메모리가 할당되므로 메모리 누수를 방지하려면 라이브러리를 할당 해제해야 한다. 또한 라이브러리를 언로드하지 못하면 라이브러리가 포함된 컴퓨터 파일에 대한 파일 시스템 작업이 방해될 수 있다. 그러나 DLL을 언로드할 때 기본 애플리케이션의 객체가 DLL 내에서 할당된 메모리를 참조하는 경우 프로그램이 충돌할 수 있다. 예를 들어 DLL이 새로운 클래스를 도입하고 DLL이 닫히면 기본 애플리케이션에서 해당 클래스의 인스턴스에 대한 추가 작업이 메모리 액세스 위반을 일으킬 수 있다. 마찬가지로 DLL이 동적으로 로드된 클래스를 인스턴스화하기 위한 팩토리 함수를 도입한 경우, DLL이 닫힌 후 해당 함수를 호출하거나 역참조하면 정의되지 않은 동작이 발생한다.

4. 6. 특수 라이브러리

유닉스 계열 운영 체제 및 윈도우에서는 실행 중인 프로세스에서 심볼을 추출할 수 있다. 유닉스 계열 운영 체제에서는 `dlopen(NULL, 0)`을, 윈도우에서는 `GetModuleHandle(NULL)`을 사용한다.

유닉스 계열 운영 체제에서는 기본 실행 파일과 이후에 로드된 동적 라이브러리를 모두 포함하는 전역 심볼 테이블에 접근할 수 있다.

윈도우에서는 기본 실행 파일에서 내보낸 심볼에 접근할 수 있다. 윈도우는 전역 심볼 테이블을 사용하지 않으며, 여러 모듈을 검색하여 이름으로 심볼을 찾는 API가 없다.

5. 자바

자바에서 클래스는 `ClassLoader` 객체를 사용하여 동적으로 로드할 수 있다. 예시는 다음과 같다:

```java

Class type = ClassLoader.getSystemClassLoader().loadClass(name);

Object obj = type.newInstance();

```

리플렉션 메커니즘은 또한 클래스가 이미 로드되지 않았다면 클래스를 로드하는 수단을 제공한다. 현재 클래스의 클래스로더를 사용한다.

```java

Class type = Class.forName(name);

Object obj = type.newInstance();

```

그러나 제어된 방식으로 클래스를 언로드하는 간단한 방법은 없다. 로드된 클래스는 클래스를 로드하는 데 사용된 클래스 로더가 시스템 클래스 로더가 아니고, 그 자체가 언로드될 때 (즉, 프로그래머가 이 작업을 원할 때)만 제어된 방식으로 언로드될 수 있다. 이 경우 클래스가 실제로 언로드되었는지 확인하기 위해 다양한 세부 사항을 관찰해야 하므로, 클래스 언로드는 번거로운 작업이 된다.

클래스의 암묵적인 언로드, 즉 가비지 수집기에 의한 제어되지 않은 방식은 자바에서 몇 번 변경되었다. 자바 1.2까지 가비지 수집기는 클래스를 로드하는 데 사용된 클래스 로더와 관계없이 공간이 필요하다고 느낄 때마다 클래스를 언로드할 수 있었다. 자바 1.2부터 시스템 클래스 로더를 통해 로드된 클래스는 절대 언로드되지 않았고, 다른 클래스 로더를 통해 로드된 클래스는 해당 클래스 로더가 언로드될 때만 언로드되었다. 자바 6부터 클래스는 가비지 수집기가 원할 경우 언로드될 수 있음을 나타내는 내부 마커를 포함할 수 있으며, 이는 클래스를 로드하는 데 사용된 클래스 로더와 관계없이 작동한다. 가비지 수집기는 이 힌트를 무시할 수 있다.

마찬가지로, 네이티브 메서드를 구현하는 라이브러리는 `System.loadLibrary` 메서드를 사용하여 동적으로 로드된다. `System.unloadLibrary` 메서드는 없다.

6. 동적 적재를 지원하지 않는 플랫폼

벨 연구소플랜 9와 그 후속작인 9front는 동적 연결을 "유해하다"고 여겨 의도적으로 피했다. Go 프로그래밍 언어는 플랜 9의 일부 개발자들이 참여했으며, 초기에는 동적 연결을 지원하지 않았으나, 2017년 2월 [https://tip.golang.org/doc/go1.8 Go 1.8]부터 플러그인 로딩을 사용할 수 있게 되었다. Go 런타임과 모든 라이브러리 함수는 컴파일된 바이너리에 정적으로 연결된다.



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com