업데이트: 2007년 11월
이전 항목에서는 응용 프로그램과 프로파일러가 실행될 때 발생하는 상황을 설명했습니다. 이제 응용 프로그램이 시작될 때 응용 프로그램과 프로파일러를 연결하는 방법을 알아 보겠습니다. CLR(공용 언어 런타임)에서는 각 프로세스에서 초기화되는 동안 연결을 설정하고 프로파일러에 연결할지 여부를 결정합니다. 연결하려는 경우 다음 순서로 두 개의 환경 변수 값을 검사하여 프로파일러를 찾습니다.
COR_ENABLE_PROFILING: 이 환경 변수가 있고 1로 설정되어야 CLR이 프로파일러에 연결됩니다.
COR_PROFILER: COR_ENABLE_PROFILING이 검사를 통과하는 경우 이전에 레지스트리에 저장된 이 CLSID 또는 ProgID가 있는 프로파일러에 CLR이 연결됩니다. 다음 두 예제에서처럼 COR_PROFILER 환경 변수는 문자열로 정의됩니다.
set COR_PROFILER={32E2F4DA-1BEA-47ea-88F9-C5DAF691C94A} set COR_PROFILER="MyProfiler"
따라서 CLR 응용 프로그램을 프로파일링하려면 응용 프로그램을 실행하기 전에 COR_ENABLE_PROFILING 및 COR_PROFILER 환경 변수를 설정해야 합니다. 또한 프로파일러 DLL이 등록되었는지 확인해야 합니다.
환경 변수 범위
COR_ENABLE_PROFILING 및 COR_PROFILER 환경 변수를 설정한 방법에 따라 영향을 미치는 범위가 달라집니다. 다음 방법 중 하나를 사용하여 이러한 변수를 설정할 수 있습니다.
ICorDebug::CreateProcess 호출에서 변수를 설정하는 경우 당시에 실행 중인 응용 프로그램에만 해당 변수가 적용됩니다. 환경을 상속하는 해당 응용 프로그램에서 시작된 다른 응용 프로그램에도 해당 변수가 적용됩니다.
명령 프롬프트 창에서 변수를 설정하는 경우 해당 창에서 시작된 모든 응용 프로그램에 해당 변수가 적용됩니다.
사용자 수준에서 변수를 설정하는 경우 Windows 탐색기로 시작하는 모든 응용 프로그램에 해당 변수가 적용됩니다. 변수를 설정한 후 여는 명령 프롬프트 창에는 이러한 환경 설정이 있으며 해당 창에서 시작하는 응용 프로그램도 마찬가지입니다. 사용자 수준에서 환경 변수를 설정하려면 내 컴퓨터를 마우스 오른쪽 단추로 클릭하고 속성, 고급 탭, 환경 변수를 차례로 클릭한 다음 사용자 변수 목록에 변수를 추가합니다.
컴퓨터 수준에서 변수를 설정하는 경우 해당 컴퓨터에서 시작된 모든 응용 프로그램에 해당 변수가 적용됩니다. 해당 컴퓨터에서 여는 명령 프롬프트 창에는 이러한 환경 설정이 있으며 해당 창에서 시작하는 응용 프로그램도 마찬가지입니다. 즉, 해당 컴퓨터의 관리되는 프로세스가 모두 프로파일러로 시작됩니다. 컴퓨터 수준에서 환경 변수를 설정하려면 내 컴퓨터를 마우스 오른쪽 단추로 클릭하고 속성, 고급 탭, 환경 변수를 차례로 클릭한 다음 시스템 변수 목록에 변수를 추가하고 컴퓨터를 다시 시작합니다. 다시 시작한 후 시스템 전체에서 변수를 사용할 수 있습니다.
Windows 서비스를 프로파일링하는 경우 환경 변수를 설정하고 프로파일러 DLL을 등록한 후 컴퓨터를 다시 시작해야 합니다. 이러한 고려 사항에 대한 자세한 내용은 Windows 서비스 프로파일링을 참조하십시오.
추가 고려 사항
프로파일러 클래스는 ICorProfilerCallback 및 ICorProfilerCallback2 인터페이스를 구현합니다. .NET Framework 2.0에서는 프로파일러가 ICorProfilerCallback2를 구현해야 합니다. 그렇지 않으면 ICorProfilerCallback2가 로드되지 않습니다.
지정한 환경에서 한 번에 하나의 프로파일러에서만 프로세스를 프로파일링할 수 있습니다. 서로 다른 환경에서 서로 다른 두 개의 프로파일러를 등록할 수 있지만 각 프로파일러는 별도의 프로세스를 프로파일링해야 합니다. 프로파일러는 프로파일링되는 프로세스와 같은 주소 공간에 매핑되는 in-process COM 서버 DLL로 구현되어야 합니다. 즉, 프로파일러는 in-process로 실행됩니다. .NET Framework에서는 다른 형식의 COM 서버를 지원하지 않습니다. 예를 들어 프로파일러가 원격 컴퓨터의 응용 프로그램을 모니터링하려면 각 컴퓨터에서 수집기 에이전트를 구현해야 합니다. 이러한 에이전트는 결과를 일괄 처리하고 중앙 데이터 수집 컴퓨터에 전달합니다.
프로파일러는 in-process로 인스턴스화된 COM 개체이므로 프로파일링된 각 응용 프로그램마다 고유한 프로파일러 복사본이 있습니다. 따라서 단일 프로파일러 인스턴스에서 여러 응용 프로그램의 데이터를 처리할 필요가 없습니다. 그러나 프로파일러의 로깅 코드에 논리를 추가하여 프로파일링된 다른 응용 프로그램에서 로그 파일을 덮어쓰지 않도록 해야 합니다.
프로파일러 초기화
두 환경 변수가 검사를 통과하는 경우 CLR은 COM CoCreateInstance 함수와 비슷한 방법으로 프로파일러 인스턴스를 만듭니다. 프로파일러는 CoCreateInstance를 직접 호출하여 로드되지 않습니다. 따라서 스레딩 모델 설정이 필요한 CoInitialize 호출은 사용되지 않습니다. 그런 다음 CLR은 프로파일러에서 ICorProfilerCallback::Initialize 메서드를 호출합니다. 이 메서드의 시그니처는 다음과 같습니다.
HRESULT Initialize(IUnknown *pICorProfilerInfoUnk)
프로파일러는 프로파일링하는 동안 pICorProfilerInfoUnk에 ICorProfilerInfo 또는 ICorProfilerInfo2 인터페이스 포인터를 쿼리하고, 나중에 더 많은 정보를 요청할 수 있도록 저장해야 합니다.
이벤트 알림 설정
그런 다음 프로파일러는 ICorProfilerInfo::SetEventMask 메서드를 호출하여 원하는 알림의 범주를 지정합니다. 예를 들어 프로파일러가 함수 enter 및 leave 알림과 가비지 수집 알림만 원하는 경우 다음을 지정합니다.
ICorProfilerInfo* pInfo;
pICorProfilerInfoUnk->QueryInterface(IID_ICorProfilerInfo, (void**)&pInfo);
pInfo->SetEventMask(COR_PRF_MONITOR_ENTERLEAVE | COR_PRF_MONITOR_GC)
이 방법으로 알림 마스크를 설정하면 프로파일러가 받는 알림을 제한할 수 있습니다. 이 방법을 사용하여 단순 또는 특수 프로파일러를 효과적으로 빌드할 수 있습니다. 또한 프로파일러에서 무시하는 알림을 보내는 데 낭비되는 CPU 시간이 줄어듭니다.
일부 프로파일러 이벤트는 변경할 수 없습니다. 즉 ICorProfilerCallback::Initialize 콜백에서 이러한 이벤트가 일단 설정되면 해당 이벤트를 해제할 수 없으며 새 이벤트를 설정할 수 없습니다. 변경할 수 없는 이벤트를 변경하려고 하면 ICorProfilerInfo::SetEventMask에서 실패한 HRESULT를 반환합니다.