Sdílet prostřednictvím


Přehled profilace

Profiler je nástroj, který monitoruje provádění jiné aplikace. Profiler CLR (Common Language Runtime) je dynamická knihovna odkazů (DLL), která se skládá z funkcí, které přijímají zprávy a odesílají zprávy do CLR pomocí rozhraní API pro profilaci. Knihovna DLL profileru je načtena clr v době běhu.

Tradiční nástroje pro profilaci se zaměřují na měření provádění aplikace. To znamená, že měří čas strávený v jednotlivých funkcích nebo využití paměti aplikace v průběhu času. Rozhraní API pro profilaci cílí na širší třídu diagnostických nástrojů, jako jsou nástroje pokrytí kódu a dokonce i pokročilé ladicí pomůcky. Tato použití jsou veškerá diagnostika v přírodě. Rozhraní API pro profilaci měří nejen míry, ale také monitoruje provádění aplikace. Z tohoto důvodu by rozhraní API pro profilaci nemělo být nikdy používáno samotnou aplikací a spuštění aplikace by nemělo záviset na profileru (nebo na něm být ovlivněno).

Profilace aplikace CLR vyžaduje větší podporu než profilace konvenčně kompilovaného strojového kódu. Důvodem je to, že CLR zavádí koncepty, jako jsou domény aplikací, uvolňování paměti, spravované zpracování výjimek, kompilace kódu za běhu (JIT) (převod společného zprostředkujícího jazyka nebo CIL, kódu na nativní strojový kód) a podobné funkce. Konvenční mechanismy profilace nemohou identifikovat nebo poskytnout užitečné informace o těchto funkcích. Rozhraní API pro profilaci poskytuje tyto chybějící informace efektivně s minimálním účinkem na výkon CLR a profilované aplikace.

Kompilace JIT za běhu poskytuje dobré příležitosti pro profilaci. Rozhraní API pro profilaci umožňuje profileru změnit stream kódu CIL v paměti pro rutinu před kompilací JIT. Tímto způsobem může profiler dynamicky přidávat instrumentační kód do konkrétních rutin, které potřebují hlubší šetření. I když je tento přístup možný v konvenčních scénářích, je mnohem jednodušší implementovat modul CLR pomocí rozhraní API pro profilaci.

Rozhraní API pro profilaci

Rozhraní API pro profilaci se obvykle používá k zápisu profileru kódu, což je program, který monitoruje provádění spravované aplikace.

Rozhraní API pro profilaci se používá knihovnou DLL profileru, která se načte do stejného procesu jako aplikace, která se profiluje. Knihovna DLL profileru implementuje rozhraní zpětného volání (ICorProfilerCallback v rozhraní .NET Framework verze 1.0 a 1.1, ICorProfilerCallback2 ve verzi 2.0 a novější). CLR volá metody v tomto rozhraní, které upozorní profiler událostí v profilovaném procesu. Profiler může volat zpět do modulu runtime pomocí metod v rozhraní ICorProfilerInfo a ICorProfilerInfo2 získat informace o stavu profilované aplikace.

Poznámka:

Ve stejném procesu jako profilovaná aplikace by měla být spuštěna pouze část řešení profileru pro shromažďování dat. Všechna uživatelská rozhraní a analýza dat by se měly provádět v samostatném procesu.

Následující obrázek ukazuje, jak knihovna DLL profileru komunikuje s aplikací, která je profilována, a CLR.

Snímek obrazovky znázorňující architekturu profilace

Rozhraní oznámení

ICorProfilerCallback a ICorProfilerCallback2 lze považovat za rozhraní oznámení. Tato rozhraní se skládají z metod, jako jsou ClassLoadStarted, ClassLoadFinished a JITCompilationStarted. Pokaždé, když CLR načte nebo uvolní třídu, zkompiluje funkci atd., volá odpovídající metodu v profileru ICorProfilerCallback nebo ICorProfilerCallback2 rozhraní.

Profiler může například měřit výkon kódu prostřednictvím dvou oznamovacích funkcí: FunctionEnter2 a FunctionLeave2. Každé oznámení pouze časového razítka, shromažďuje výsledky a výstupy seznamu, který označuje, které funkce spotřebovávají nejvíce procesoru nebo hodinových hodin během provádění aplikace.

Rozhraní pro načítání informací

Další hlavní rozhraní zapojená do profilace jsou ICorProfilerInfo a ICorProfilerInfo2. Profiler volá tato rozhraní podle potřeby, aby získal další informace, které jí pomůžou s analýzou. Například pokaždé, když CLR volá funkci FunctionEnter2 , poskytuje identifikátor funkce. Profiler může získat další informace o této funkci voláníM ICorProfilerInfo2::GetFunctionInfo2 metoda zjistit nadřazenou třídu funkce, její název atd.

Podporované funkce

Rozhraní API pro profilaci poskytuje informace o různých událostech a akcích, ke kterým dochází v modulu CLR (Common Language Runtime). Tyto informace můžete použít k monitorování vnitřních pracovních postupů procesů a k analýze výkonu aplikace .NET Framework.

Rozhraní API pro profilaci načte informace o následujících akcích a událostech, ke kterým dochází v modulu CLR:

  • Události spuštění a vypnutí CLR.

  • Události vytváření a vypnutí domény aplikace

  • Načítání a uvolňování událostí sestavení

  • Načítání a uvolňování událostí modulu

  • Události vytváření a zničení virtuálních tabulek MODELU COM.

  • Kompilace za běhu (JIT) a události pro vytváření kódu

  • Načítání a uvolňování událostí třídy

  • Události vytváření a zničení vláken.

  • Události vstupu a ukončení funkce

  • Výjimky:

  • Přechody mezi spravovaným a nespravovaným spuštěním kódu

  • Přechody mezi různými kontexty modulu runtime

  • Informace o pozastaveních za běhu

  • Informace o haldě paměti modulu runtime a aktivitě uvolňování paměti paměti.

Rozhraní API pro profilaci je možné volat z libovolného (nespravovaný) jazyka kompatibilního s modelem COM.

Rozhraní API je efektivní s ohledem na využití procesoru a paměti. Profilace nezahrnuje změny profilované aplikace, které jsou dostatečně významné, aby způsobily zavádějící výsledky.

Rozhraní API pro profilaci je užitečné jak pro vzorkování, tak pro profilátory bez vzorkování. Profiler vzorkování zkontroluje profil v pravidelných hodinách, například v 5 milisekundách od sebe. Profiler bez vzorkování je informován o události synchronně s vláknem, které událost způsobuje.

Nepodporované funkce

Rozhraní API pro profilaci nepodporuje následující funkce:

  • Nespravovaný kód, který musí být profilován pomocí konvenčních metod Win32. Profiler CLR však zahrnuje přechodové události, které určují hranice mezi spravovaným a nespravovaným kódem.

  • Vlastní úpravy aplikací, které upravují vlastní kód pro účely, jako je programování orientované na aspekt.

  • Kontrola hranic, protože rozhraní API pro profilaci tyto informace neposkytuje. CLR poskytuje vnitřní podporu pro kontrolu hranic všech spravovaných kódů.

  • Vzdálená profilace, která není podporována z následujících důvodů:

    • Vzdálená profilace prodlužuje dobu provádění. Při použití rozhraní profilace je nutné minimalizovat dobu provádění, aby výsledky profilace nebyly neoprávněně ovlivněny. To platí zejména v případě, že se monitoruje výkon spouštění. Vzdálená profilace ale není omezením, pokud se rozhraní profilace používají k monitorování využití paměti nebo k získání informací o rámech zásobníku, objektech atd.

    • Profiler kódu CLR musí zaregistrovat jedno nebo více rozhraní zpětného volání s modulem runtime v místním počítači, na kterém je profilovaná aplikace spuštěná. Tím se omezí možnost vytvořit vzdálený profiler kódu.

Vlákna oznámení

Ve většině případů vlákno, které generuje událost, také spouští oznámení. Taková oznámení (například FunctionEnter a FunctionLeave) nemusí explicitní ThreadID. Profiler se také může rozhodnout použít místní úložiště vláken k ukládání a aktualizaci svých analytických bloků místo indexování bloků analýzy v globálním úložišti na ThreadID základě ovlivněného vlákna.

Všimněte si, že tyto zpětná volání nejsou serializována. Uživatelé musí chránit svůj kód vytvořením datových struktur bezpečných pro přístup z více vláken a uzamčením kódu profileru, pokud je to nutné, aby se zabránilo paralelnímu přístupu z více vláken. Proto v některých případech můžete obdržet neobvyklou posloupnost zpětných volání. Předpokládejme například, že spravovaná aplikace vytváří dvě vlákna, která spouští stejný kód. V tomto případě je možné přijmout ICorProfilerCallback::JITCompilationStarted událost pro některé funkce z jednoho vlákna a FunctionEnter zpětné volání z druhého vlákna před přijetím ICorProfilerCallback::JITCompilationFinished zpětné volání. V tomto případě uživatel obdrží FunctionEnter zpětné volání pro funkci, která ještě nebyla plně zkompilována za běhu (JIT).

Zabezpečení

Knihovna DLL profileru je nespravovaná knihovna DLL, která se spouští jako součást modulu spouštění modulu CLR (Common Language Runtime). V důsledku toho kód v knihovně DLL profileru podléhá omezením zabezpečení přístupu ke spravovanému kódu. Jediná omezení knihovny DLL profileru jsou omezení uložená operačním systémem na uživatele, který spouští profilovanou aplikaci.

Autoři profileru by měli podniknout vhodná opatření, aby se vyhnuli problémům souvisejícím se zabezpečením. Během instalace by například měla být přidána knihovna DLL profileru do seznamu řízení přístupu (ACL), aby ho uživatel se zlými úmysly nemohl upravit.

Kombinování spravovaného a nespravovaného kódu v profileru kódu

Nesprávně napsaný profiler může způsobit cyklické odkazy na sebe, což vede k nepředvídatelným chováním.

Kontrola rozhraní API pro profilaci CLR může vytvořit dojem, že můžete napsat profiler, který obsahuje spravované a nespravované komponenty, které vzájemně volají prostřednictvím zprostředkovatele komunikace modelu COM nebo nepřímých volání.

I když je to možné z hlediska návrhu, rozhraní API pro profilaci nepodporuje spravované komponenty. Profiler CLR musí být zcela nespravovaný. Pokusy o kombinování spravovaného a nespravovaného kódu v profileru CLR můžou způsobit narušení přístupu, selhání programu nebo zablokování. Spravované komponenty profileru aktivují události zpět do nespravovaných komponent, které by následně znovu volaly spravované komponenty, což vede k cyklický odkaz.

Jediné umístění, kde může profiler CLR bezpečně volat spravovaný kód, je v těle CIL (Common Intermediate Language) metody. Doporučeným postupem pro úpravu těla CIL je použití metod rekompilace JIT v rozhraní ICorProfilerCallback4 .

Ke změně souboru CIL je také možné použít starší metody instrumentace. Před dokončením kompilace funkce za běhu (JIT) může profiler vložit spravovaná volání do těla CIL metody a pak jiT-compile it (viz ICorProfilerInfo::GetILFunctionBody metoda). Tuto techniku lze úspěšně použít pro selektivní instrumentaci spravovaného kódu nebo ke shromažďování statistik a údajů o výkonu o JIT.

Případně může profiler kódu vložit nativní háky do těla CIL každé spravované funkce, která volá nespravovaný kód. Tuto techniku lze použít pro instrumentaci a pokrytí. Profiler kódu může například vložit instrumentační háky za každý blok CIL, aby se zajistilo, že se blok spustil. Úprava těla CIL metody je velmi delikátní operace a existuje mnoho faktorů, které je třeba vzít v úvahu.

Profilace nespravovaného kódu

Rozhraní CLR (Common Language Runtime) pro profilaci poskytuje minimální podporu pro profilaci nespravovaného kódu. K dispozici jsou tyto funkce:

  • Výčet řetězů zásobníku Tato funkce umožňuje profileru kódu určit hranici mezi spravovaným kódem a nespravovaným kódem.

  • Určení, zda řetěz zásobníku odpovídá spravovanému kódu nebo nativnímu kódu.

V rozhraní .NET Framework verze 1.0 a 1.1 jsou tyto metody k dispozici prostřednictvím podmnožina rozhraní API pro ladění CLR v procesu. Jsou definovány v souboru CorDebug.idl.

V rozhraní .NET Framework 2.0 a novějších můžete pro tuto funkci použít metodu ICorProfilerInfo2::D oStackSnapshot .

Použití modelu COM

I když jsou rozhraní profilace definována jako rozhraní MODELU COM, modul CLR (Common Language Runtime) ve skutečnosti neicializuje com pro použití těchto rozhraní. Důvodem je vyhnout se nutnosti nastavit model vláken pomocí funkce CoInitialize dříve, než spravovaná aplikace měla šanci určit požadovaný model podprocesů. Podobně by profiler sám neměl volat CoInitialize, protože může vybrat model vláken, který není kompatibilní s profilem aplikace a může způsobit selhání aplikace.

Zásobníky volání

Rozhraní API pro profilaci poskytuje dva způsoby, jak získat zásobníky volání: metodu snímku zásobníku, která umožňuje řídké shromažďování zásobníků volání a metodu stínového zásobníku, která sleduje zásobník volání vždy.

Snímek zásobníku

Snímek zásobníku je trasování zásobníku vlákna v okamžiku. Rozhraní API pro profilaci podporuje trasování spravovaných funkcí v zásobníku, ale trasování nespravovaných funkcí ponechá u vlastního walkeru zásobníku profileru.

Další informace o tom, jak programovat profiler pro procházku spravovaných zásobníků, naleznete v ICorProfilerInfo2::D oStackSnapshot metoda v této dokumentace sada a Profiler Stack Walking v rozhraní .NET Framework 2.0: Základy a beyond.

Stínový zásobník

Použití metody snímků příliš často může rychle vytvořit problém s výkonem. Pokud chcete trasování zásobníku často používat, měl by váš profiler místo toho vytvořit stínový zásobník pomocí zpětného volání functionEnter2, FunctionLeave2, FunctionTailcall2 a ICorProfilerCallback2 výjimky. Stínový zásobník je vždy aktuální a kdykoli je potřeba snímek zásobníku, můžete ho rychle zkopírovat do úložiště.

Stínový zásobník může získat argumenty funkce, návratové hodnoty a informace o obecných instancích. Tyto informace jsou k dispozici pouze prostřednictvím stínového zásobníku a mohou být získány při předání ovládacího prvku funkci. Tyto informace však nemusí být později během spuštění funkce k dispozici.

Zpětná volání a hloubka zásobníku

Zpětné volání profileru může být vydáno za velmi omezených okolností a přetečení zásobníku v zpětném volání profileru povede k okamžitému ukončení procesu. Profiler by měl v reakci na zpětná volání používat co nejmenší zásobník. Pokud je profiler určený pro procesy, které jsou robustní proti přetečení zásobníku, měl by se také samotný profiler vyhnout aktivaci přetečení zásobníku.

Titulek Popis
Nastavení prostředí profilace Vysvětluje, jak inicializovat profiler, nastavit oznámení událostí a profilovat službu systému Windows.
Rozhraní pro profilaci Popisuje nespravovaná rozhraní, která rozhraní API pro profilaci používá.
Globální statické funkce pro profilaci Popisuje nespravované globální statické funkce, které používá rozhraní API pro profilaci.
Výčty pro profilaci Popisuje nespravované výčty, které používá rozhraní API pro profilaci.
Struktury pro profilaci Popisuje nespravované struktury, které používá rozhraní API pro profilaci.