Megosztás a következőn keresztül:


Profilkészítés áttekintése

A profilkészítő egy olyan eszköz, amely egy másik alkalmazás végrehajtását figyeli. A közös nyelvi futtatókörnyezeti (CLR) profilkészítő egy dinamikus csatolási kódtár (DLL), amely olyan függvényekből áll, amelyek üzeneteket fogadnak a CLR-ből, és üzeneteket küldenek a CLR-nek a profilkészítési API használatával. A profiler DLL-t a CLR futtatáskor tölti be.

A hagyományos profilkészítési eszközök az alkalmazás végrehajtásának mérésére összpontosítanak. Vagyis az egyes függvényekben töltött időt vagy az alkalmazás memóriahasználatát mérik az idő függvényében. A profilkészítési API a diagnosztikai eszközök szélesebb körét célozza meg, például a kódlefedettségi segédprogramokat és a speciális hibakeresési segédeszközöket. Ezek a felhasználások mind diagnosztikai jellegűek. A profilkészítési API nem csak méri, hanem figyeli az alkalmazások végrehajtását is. Ezért a profilkészítési API-t soha nem használhatja az alkalmazás, és az alkalmazás végrehajtása nem függhet (vagy nem befolyásolhatja) a profilkészítőt.

A CLR-alkalmazások profilkészítése több támogatást igényel, mint a hagyományosan lefordított gépi kód profilozása. Ennek az az oka, hogy a CLR olyan fogalmakat vezet be, mint az alkalmazástartományok, a szemétgyűjtés, a felügyelt kivételkezelés, a kód igény szerinti fordítása (közös köztes nyelv vagy CIL, kód natív gépi kódká alakítása) és hasonló funkciók. A hagyományos profilkészítési mechanizmusok nem tudják azonosítani vagy hasznos információkat szolgáltatni ezekről a funkciókról. A profilkészítési API hatékonyan biztosítja ezt a hiányzó információt, és minimális hatással van a CLR és a profilozott alkalmazás teljesítményére.

A JIT futásidejű összeállítása jó lehetőségeket kínál a profilkészítéshez. A profilkészítési API lehetővé teszi, hogy a profilozó a JIT-fordítás előtt módosítsa a memóriában lévő CIL-kódstreamet egy rutinhoz. Ily módon a profilkészítő dinamikusan adhat hozzá rendszerállapot-kódot azokhoz a rutinokhoz, amelyek mélyebb vizsgálatot igényelnek. Bár ez a megközelítés a hagyományos forgatókönyvekben lehetséges, a CLR-hez sokkal egyszerűbb implementálni a profilkészítési API-t.

A Profilkészítési API

A profilkészítési API-t általában kódprofilozó írására használják, amely egy felügyelt alkalmazás végrehajtását monitorozó program.

A profilkészítési API-t egy profilkészítő DLL használja, amely ugyanabba a folyamatba töltődik be, mint a profilozott alkalmazás. A profiler DLL egy visszahívási felületet implementál (az ICorProfilerCallback az .NET-keretrendszer 1.0-s és 1.1-es verziójában, az ICorProfilerCallback2 2.0-s és újabb verzióiban). A CLR meghívja az ezen a felületen található metódusokat, hogy értesítse a profilozót a profilozott folyamat eseményeiről. A profilozó az ICorProfilerInfo és az ICorProfilerInfo2 felületek metódusainak használatával visszahívhatja a futtatókörnyezetet a profilozott alkalmazás állapotával kapcsolatos információk lekéréséhez.

Feljegyzés

Csak a profilkészítő megoldás adatgyűjtési része futhat ugyanabban a folyamatban, mint a profilozott alkalmazás. Minden felhasználói felületet és adatelemzést külön folyamat során kell elvégezni.

Az alábbi ábra bemutatja, hogy a profilkészítő DLL hogyan kommunikál a profilozott alkalmazással és a CLR-vel.

Képernyőkép a profilkészítési architektúráról.

Az értesítési felületek

Az ICorProfilerCallback és az ICorProfilerCallback2 értesítési felületnek tekinthető. Ezek az interfészek olyan metódusokból állnak, mint a ClassLoadStarted, a ClassLoadFinished és a JITCompilationStarted. Minden alkalommal, amikor a CLR betölt vagy kiürít egy osztályt, lefordít egy függvényt, és így tovább, meghívja a megfelelő metódust a profilkészítőben ICorProfilerCallback vagy ICorProfilerCallback2 a felületen.

Egy profilkészítő például két értesítési függvényen keresztül mérheti a kód teljesítményét: FunctionEnter2 és FunctionLeave2. Csak időbélyegezi az egyes értesítéseket, összegyűjti az eredményeket, és egy listát ad ki, amely azt jelzi, hogy mely függvények használták a legtöbb CPU-t vagy fali órát az alkalmazás végrehajtása során.

Az információlekérési felületek

A profilkészítés többi fő felülete az ICorProfilerInfo és az ICorProfilerInfo2. A profilkészítő szükség szerint meghívja ezeket az interfészeket, hogy további információkat szerezzen az elemzéshez. Például amikor a CLR meghívja a FunctionEnter2 függvényt, egy függvényazonosítót ad meg. A profilozó az ICorProfilerInfo2::GetFunctionInfo2 metódus meghívásával további információt kaphat a függvényről, hogy felderítse a függvény szülőosztályát, nevét stb.

Támogatott szolgáltatások

A profilkészítési API számos olyan eseményről és műveletről nyújt információt, amelyek a közös nyelvi futtatókörnyezetben történnek. Ezekkel az információkkal monitorozhatja a folyamatok belső működését, és elemezheti a .NET-keretrendszer alkalmazás teljesítményét.

A profilkészítési API a következő műveletekkel és eseményekkel kapcsolatos információkat kéri le a CLR-ben:

  • CLR indítási és leállítási események.

  • Alkalmazástartomány-létrehozási és -leállítási események.

  • Összeszerelési be- és kirakodási események.

  • Modulbetöltési és -eltávolítási események.

  • COM vtable létrehozási és megsemmisítési események.

  • Igény szerinti (JIT) fordítási és kódfeldobási események.

  • Osztálybetöltési és -kirakodási események.

  • Szállétrehozás és -megsemmisítési események.

  • Függvénybeléptetési és kilépési események.

  • Kivételek.

  • Áttűnés a felügyelt és a nem felügyelt kódvégrehajtás között.

  • Áttűnések a különböző futtatókörnyezetek között.

  • Információ a futásidejű felfüggesztésekről.

  • Információk a futásidejű memória halomról és a szemétgyűjtési tevékenységről.

A profilkészítési API bármilyen (nem felügyelt) COM-kompatibilis nyelvről hívható meg.

Az API a processzor- és memóriahasználat szempontjából hatékony. A profilkészítés nem tartalmaz olyan módosításokat a profilozott alkalmazáson, amelyek elég jelentősek ahhoz, hogy félrevezető eredményeket okozzanak.

A profilkészítési API a mintavételezés és a nem mintavételező profilkészítők számára is hasznos. A mintavételezési profilozó a profilt normál órajelek, például 5 ezredmásodperc távolságra vizsgálja. A nem mintavételező profilkészítők szinkron módon értesülnek az eseményről az eseményt kiváltó szálkal.

Nem támogatott funkciók

A profilkészítési API nem támogatja a következő funkciókat:

  • Nem felügyelt kód, amelyet hagyományos Win32-módszerekkel kell profilba venni. A CLR-profilozó azonban áttűnéses eseményeket is tartalmaz a felügyelt és a nem felügyelt kód közötti határok meghatározásához.

  • Ön módosító alkalmazások, amelyek saját kódjukat módosítják olyan célokra, mint például a szempontalapú programozás.

  • Korlátok ellenőrzése, mert a profilkészítési API nem adja meg ezeket az információkat. A CLR belső támogatást nyújt az összes felügyelt kód korlátellenőrzéséhez.

  • Távoli profilkészítés, amely a következő okok miatt nem támogatott:

    • A távoli profilkészítés meghosszabbítja a végrehajtási időt. A profilkészítési felületek használatakor minimalizálnia kell a végrehajtási időt, hogy a profilkészítési eredmények ne legyenek indokolatlanul érintve. Ez különösen igaz a végrehajtási teljesítmény figyelésekor. A távoli profilkészítés azonban nem korlátozás, ha a profilkészítési felületekkel figyelik a memóriahasználatot, vagy futásidejű információkat szereznek be a veremkeretekről, objektumokról stb.

    • A CLR-kódprofilozónak regisztrálnia kell egy vagy több visszahívási felületet azon a helyi számítógépen, amelyen a profilalapú alkalmazás fut. Ez korlátozza a távoli kódprofil-kezelő létrehozását.

Értesítési szálak

A legtöbb esetben az eseményt létrehozó szál értesítéseket is végrehajt. Az ilyen értesítéseknek (például a FunctionEnternek és a FunctionLeave-nek) nem kell megadniuk az explicitt ThreadID. A profilozó dönthet úgy is, hogy a szálalapú tárolást használja az elemzési blokkok tárolására és frissítésére ahelyett, hogy az érintett szál alapján indexelné az elemzési blokkokat a ThreadID globális tárolóban.

Vegye figyelembe, hogy ezek a visszahívások nincsenek szerializálva. A felhasználóknak szálbiztos adatstruktúrák létrehozásával és a profiler kódjának zárolásával kell védeniük a kódjukat, ha szükséges, a több szál párhuzamos hozzáférésének megakadályozása érdekében. Ezért bizonyos esetekben szokatlan visszahívási sorozatot kaphat. Tegyük fel például, hogy egy felügyelt alkalmazás két szálat hoz létre, amelyek azonos kódot hajtanak végre. Ebben az esetben lehetséges egy ICorProfilerCallback::JITCompilationStarted esemény fogadása egy függvényhez az egyik szálról, egy FunctionEnter visszahívás a másik szálról az ICorProfilerCallback::JITCompilationFinished visszahívás fogadása előtt. Ebben az esetben a felhasználó visszahívást FunctionEnter kap egy olyan függvényhez, amely még nem lett teljesen időszerű (JIT) lefordítva.

Biztonság

A profiler DLL egy nem felügyelt DLL, amely a közös nyelvi futtatókörnyezet végrehajtási motorjának részeként fut. Ennek eredményeképpen a profiler DLL-jében lévő kódra nem vonatkoznak a felügyelt kódhozzáférés biztonsági korlátozásai. A profilkészítő DLL-ekre csak az operációs rendszer által a profilozott alkalmazást futtató felhasználóra vonatkozó korlátozások vonatkoznak.

A profilkészítőknek megfelelő óvintézkedéseket kell tenniük a biztonsággal kapcsolatos problémák elkerülése érdekében. A telepítés során például egy profiler DLL-t kell hozzáadni egy hozzáférés-vezérlési listához (ACL), hogy egy rosszindulatú felhasználó ne tudja módosítani.

Felügyelt és nem felügyelt kód kombinálása kódprofilozóban

A helytelenül írt profilkészítő körkörös hivatkozásokat okozhat önmagára, ami kiszámíthatatlan viselkedést eredményez.

A CLR profilkészítési API áttekintése azt a benyomást keltheti, hogy olyan profilkészítőt írhat, amely olyan felügyelt és nem felügyelt összetevőket tartalmaz, amelyek com-inop vagy közvetett hívásokon keresztül hívják egymást.

Bár ez tervezési szempontból lehetséges, a profilkészítési API nem támogatja a felügyelt összetevőket. A CLR-profilozóknak teljesen nem felügyeltnek kell lenniük. A felügyelt és a nem felügyelt kód CLR-profilkészítőben való kombinálására tett kísérletek hozzáférési szabálysértéseket, programhibákat vagy holtpontokat okozhatnak. A profilkészítő felügyelt összetevői újra aktiválják az eseményeket a nem felügyelt összetevőkre, amelyek később újra meghívják a felügyelt összetevőket, és körkörös hivatkozásokat eredményeznek.

Az egyetlen hely, ahol a CLR-profilkészítő biztonságosan meghívhatja a felügyelt kódot, a metódus közös köztes nyelvének (CIL) törzsében található. A CIL-törzs módosításának ajánlott eljárása a JIT újrafordítási módszereinek használata az ICorProfilerCallback4 felületen.

A CIL módosításához a régebbi rendszerállapot-módszereket is használhatja. Egy függvény igény szerinti (JIT) fordítása előtt a profilozó beszúrhat felügyelt hívásokat egy metódus CIL törzsébe, majd jiT-fordítást végezhet (lásd az ICorProfilerInfo::GetILFunctionBody metódust). Ez a technika sikeresen használható a felügyelt kód szelektív rendszerezéséhez, vagy a JIT-ről szóló statisztikák és teljesítményadatok gyűjtéséhez.

Másik lehetőségként a kódprofilozó natív horgokat is beszúrhat a CIL törzsébe minden felügyelt függvényhez, amely nem felügyelt kódba hív be. Ez a technika használható a rendszerezéshez és a lefedettséghez. Egy kódprofilozó például minden CIL-blokk után beszúrhat rendszerállapot-horgokat, hogy meggyőződjön arról, hogy a blokk végrehajtásra került. A módszer CIL-törzsének módosítása nagyon kényes művelet, és számos tényezőt figyelembe kell venni.

Profilkészítés nem felügyelt kód

A közös nyelvi futtatókörnyezeti (CLR) profilkészítési API minimális támogatást nyújt a nem felügyelt kód profilozásához. A következő funkciók biztosítottak:

  • Veremláncok számbavétele. Ez a funkció lehetővé teszi, hogy a kódprofilozó meghatározza a felügyelt kód és a nem felügyelt kód közötti határt.

  • Annak meghatározása, hogy egy veremlánc megfelel-e a felügyelt kódnak vagy a natív kódnak.

Az .NET-keretrendszer 1.0-s és 1.1-es verzióiban ezek a metódusok a CLR hibakeresési API folyamatközi részhalmazán keresztül érhetők el. Ezek a CorDebug.idl fájlban vannak definiálva.

A .NET-keretrendszer 2.0-s és újabb verzióiban az ICorProfilerInfo2::D oStackSnapshot metódust használhatja ehhez a funkcióhoz.

A COM használata

Bár a profilkészítési felületek COM-felületekként vannak definiálva, a közös nyelvi futtatókörnyezet (CLR) valójában nem inicializálja a COM-t ezen felületek használatára. Ennek az az oka, hogy a coInitialize függvénnyel ne kelljen beállítani a szálmodellt, mielőtt a felügyelt alkalmazásnak lehetősége lett volna megadni a kívánt szálmodellt. Hasonlóképpen, maga a profilozó nem hívható CoInitializemeg, mert olyan szálmodellt választhat, amely nem kompatibilis a profilozott alkalmazással, és az alkalmazás meghiúsulását okozhatja.

Hívássorozatok

A profilkészítési API két módszert kínál a hívásveremek beszerzésére: egy verem-pillanatkép-metódust, amely lehetővé teszi a hívásveremek ritkán történő gyűjtését, valamint egy árnyékverem-metódust, amely minden pillanatban nyomon követi a hívásvermet.

Verem pillanatképe

A verem-pillanatképek egy szál veremének nyomait ábrázolják azonnal. A profilkészítési API támogatja a felügyelt függvények nyomkövetését a veremen, de a nem felügyelt függvények nyomkövetését a profilozó saját veremkövetőjének hagyja.

A profilkészítő felügyelt veremek sétáltatására való programozásával kapcsolatos további információkért tekintse meg az ICorProfilerInfo2::D oStackSnapshot metódust ebben a dokumentációs készletben, valamint a Profiler Stack Walkingot a .NET-keretrendszer 2.0: Basics and Beyond című .NET-keretrendszer.

Árnyékverem

Ha túl gyakran használja a pillanatképet, az gyorsan teljesítményproblémát okozhat. Ha gyakran szeretne stack-nyomkövetéseket végezni, a profilkészítőnek ehelyett árnyékvermet kell létrehoznia a FunctionEnter2, a FunctionLeave2, a FunctionTailcall2 és az ICorProfilerCallback2 kivételvisszahívások használatával. Az árnyékverem mindig aktuális, és gyorsan átmásolható a tárolóba, amikor szükség van egy verem pillanatképére.

Az árnyékverem függvényargumentumokat, visszaadott értékeket és általános példányokra vonatkozó információkat szerezhet be. Ez az információ csak az árnyékveremen keresztül érhető el, és akkor szerezhető be, ha a vezérlőt egy függvénynek adják át. Előfordulhat azonban, hogy ez az információ később nem érhető el a függvény futtatása során.

Visszahívások és veremmélység

A profilkészítő visszahívások nagyon halmozott körülmények között is kiadhatók, és a profilkészítő visszahívásokban a verem túlcsordulása azonnali folyamatkimenethez vezet. A profilkészítőnek a lehető legkevesebb vermet kell használnia a visszahívásokra válaszul. Ha a profilkészítőt olyan folyamatokhoz szánták, amelyek robusztusak a verem túlcsordulása ellen, akkor magának a profilozónak is el kell kerülnie a verem túlcsordulását.

Cím Leírás
Profilkészítési környezet beállítása Ez a cikk bemutatja, hogyan inicializálhat egy profilkészítőt, állíthat be eseményértesítéseket és profilt a Windows-szolgáltatásokban.
Profilkészítési felületek A profilkészítési API által használt nem felügyelt felületeket ismerteti.
Globális statikus függvények profilozása A profilkészítési API által használt nem felügyelt globális statikus függvényeket ismerteti.
Enumerálások profilkészítése A profilkészítési API által használt nem felügyelt enumerálásokat ismerteti.
Profilkészítési struktúrák A profilkészítési API által használt nem felügyelt struktúrákat ismerteti.