DLL과 가상메모리 주소
글쓴이: kyj_kr / 작성시간: 토, 2021/03/06 - 11:41오후
DLL과 같은 공유 라이브러리 같은 경우, 최초 로딩시에 실제 메모리 상에 올라가고 이후 다른 프로세스에서 로딩을 시도하면 그냥 실제메모리-가상메모리 간 매핑만 시켜주기만 하면 되는게 공유가 되는 원리 아닌가요?
그런데,
1. 프로세스 A가 실행되며 X.dll을 로드한다.
따라서 X.dll은 A의 가상 메모리 영역에 맵핑되면서 물리 메모리에 할당된다.
2. 프로세스 B가 실행되며 X.dll을 로드한다.
이미 1단계에서 X.dll이 물리 메모리에 올라 있으므로 그대로 참조할 수 있도록
프로세스 B의 가상 메모리 영역에 맵핑만 한다.
이 상황에서 유의할 것이 X.dll 이 할당된 가상 메모리 주소이다.
프로세스 A와 B가 동일한 주소에 할당한다. 이것이 DLL 공유가 가능한 이유이다.
다시 말해서 두 프로세스가 동일한 DLL을 동일한 가상 주소에 맵핑했기 때문에,
페이지 단위로 공유가 가능하다는 것이다.
[출처] http://egloos.zum.com/sweeper/v/1792902
구글 검색 중에 이런 글을 보게 되었는데, 위 글 내용중에 "프로세스 A와 B가 동일한 주소에 할당한다. 이것이 DLL 공유가 가능한 이유이다."라는 문구가 이해가 가질 않습니다. 왜냐하면, 프로세스A와 프로세스B가 동일한 가상메모리 주소에 할당하지 않고, 그냥 실제메모리와 매핑만 잘시켜주면 그게 DLL 공유가 가능한 이유 아닌가요?
Forums:
프로그램마다 할당되는 메모리 영역이 다르기 때문에
프로그램마다 할당되는 메모리 영역이 다르기 때문에 다른 메모리 영역의 dll 에는 접근할 수 없습니다.
그 블로그의 언급이 맞는 것 같습니다.
그 블로그의 언급이 맞는 것 같습니다.
DLL 코드가 프로세스마다 서로 다른 가상메모리 주소로 매핑될 경우라도, DLL 코드에 변경만 없다면 실제메모리 공간 공유에는 문제가 생기지 않겠으나,
실상은 DLL 로드시 매핑주소가 달라지면 DLL 코드중 점프명령 등도 따라 수정되는 코드재배치(relocation)가 이뤄지므로 DLL 코드를 담고 있는 메모리페이지에 거의 필연적으로 쓰기가 발생하게 됩니다. 그 결과로 Copy-on-write protection에 의해 해당 페이지는 새 메모리페이지로 복사이동되므로 더이상 타 프로세스와 공유될 수 없게 되고요.
즉, 해당 DLL이 동일 가상주소로(default base address로) 로드된 프로세스들끼리는 DLL 코드페이지 전체가 공유되지만, 다른 주소로 로드된 프로세스의 경우엔 CoW가 발생하지 않은 페이지들만 공유되는 것 같습니다. 잘 아는 것은 아니고, 잠시 호기심이 생겨 아래의 MS 자료를 참고하여 얻은 결론입니다.
Loading Applications and DLLs
https://docs.microsoft.com/en-us/windows/win32/memory/memory-protection
감사합니다!
작성하신분 덕에 이해가 되었네요!
핵심은 Dll code의 relocation과 Cow군요.
예상치도 못했는데 개운한 느낌 얻고 갑니다.
감사합니다!
댓글 달기