Bagikan melalui


Ringkasan Pembuatan Profil

Profiler adalah alat yang memantau eksekusi aplikasi lain. Profiler runtime bahasa umum (CLR) adalah pustaka link dinamis (DLL) yang terdiri dari fungsi yang menerima pesan dari, dan mengirim pesan ke, CLR dengan menggunakan API profil. DLL profiler dimuat oleh CLR pada saat run time.

Alat pembuatan profil tradisional berfokus pada pengukuran eksekusi aplikasi. Artinya, mereka mengukur waktu yang dihabiskan di setiap fungsi atau penggunaan memori aplikasi dari waktu ke waktu. API profil menargetkan kelas alat diagnostik yang lebih luas seperti utilitas cakupan kode dan bahkan alat bantu penelusuran kesalahan tingkat lanjut. Semua kegunaan ini bersifat diagnostik. API pembuatan profil tidak hanya mengukur tetapi juga memantau eksekusi aplikasi. Karena alasan ini, API pembuatan profil tidak boleh digunakan oleh aplikasi itu sendiri, dan eksekusi aplikasi tidak boleh bergantung pada (atau dipengaruhi oleh) pembuat profil.

Pembuatan profil aplikasi CLR membutuhkan lebih banyak dukungan daripada pembuatan profil kode mesin yang dikompilasi secara konvensional. Ini karena CLR memperkenalkan konsep seperti domain aplikasi, pengumpulan sampah, penanganan pengecualian terkelola, kompilasi kode just-in-time (JIT) (mengonversi bahasa perantara umum, atau CIL, kode menjadi kode mesin asli), dan fitur serupa. Mekanisme pembuatan profil konvensional tidak dapat mengidentifikasi atau memberikan informasi yang berguna tentang fitur-fitur ini. API pembuatan profil menyediakan informasi yang hilang ini secara efisien, dengan efek minimal pada performa CLR dan aplikasi yang dibuat profilnya.

Kompilasi JIT saat run time memberikan peluang yang bagus untuk pembuatan profil. API pembuatan profil memungkinkan profiler mengubah aliran kode CIL dalam memori untuk rutinitas sebelum dikompilasi JIT. Dengan cara ini, profiler dapat secara dinamis menambahkan kode instrumentasi ke rutinitas tertentu yang membutuhkan penyelidikan lebih dalam. Meskipun pendekatan ini dimungkinkan dalam skenario konvensional, namun jauh lebih mudah untuk diterapkan untuk CLR dengan menggunakan API pembuatan profil.

API Pembuatan Profil

Biasanya, API pembuatan profil digunakan untuk menulis profil kode, yang merupakan program yang memantau eksekusi aplikasi terkelola.

API pembuatan profil digunakan oleh profiler DLL, yang dimuat ke dalam proses yang sama dengan aplikasi yang sedang diprofilkan. DLL profiler mengimplementasikan antarmuka panggilan balik (ICorProfilerCallback di .NET Framework versi 1.0 dan 1.1, ICorProfilerCallback2 di versi 2.0 dan yang lebih baru). CLR memanggil metode di antarmuka itu untuk memberi tahu profiler tentang peristiwa dalam proses yang diprofilkan. Profiler dapat memanggil kembali ke runtime dengan menggunakan metode di antarmuka ICorProfilerInfo dan ICorProfilerInfo2 untuk mendapatkan informasi tentang status aplikasi yang diprofilkan.

Catatan

Hanya bagian pengumpulan data dari solusi profiler yang harus berjalan dalam proses yang sama dengan aplikasi yang diprofilkan. Semua antarmuka pengguna dan analisis data harus dilakukan dalam proses terpisah.

Ilustrasi berikut menunjukkan bagaimana profiler DLL berinteraksi dengan aplikasi yang sedang diprofilkan dan CLR.

Cuplikan layar yang memperlihatkan arsitektur pembuatan profil.

Antarmuka Pemberitahuan

ICorProfilerCallback dan ICorProfilerCallback2 dapat dianggap sebagai antarmuka pemberitahuan. Antarmuka ini terdiri dari metode seperti ClassLoadStarted, ClassLoadFinished, dan JITCompilationStarted. Setiap kali CLR memuat atau membongkar kelas, mengompilasi fungsi, dan seterusnya, CLR memanggil metode yang sesuai di antarmuka ICorProfilerCallback atau ICorProfilerCallback2 profiler.

Misalnya, profiler dapat mengukur performa kode melalui dua fungsi pemberitahuan: FunctionEnter2 dan FunctionLeave2. Itu hanya menandai waktu setiap pemberitahuan, mengumpulkan hasil, dan mengeluarkan daftar yang menunjukkan fungsi mana yang paling banyak menghabiskan waktu CPU atau jam dinding selama eksekusi aplikasi.

Antarmuka Pengambilan Informasi

Antarmuka utama lainnya yang terlibat dalam pembuatan profil adalah ICorProfilerInfo dan ICorProfilerInfo2. Profiler memanggil antarmuka ini sesuai kebutuhan untuk mendapatkan lebih banyak informasi guna membantu analisisnya. Misalnya, setiap kali CLR memanggil fungsi FunctionEnter2, ia menyediakan pengidentifikasi fungsi. Profiler dapat memperoleh informasi lebih lanjut tentang fungsi tersebut dengan memanggil metode ICorProfilerInfo2::GetFunctionInfo2 untuk menemukan kelas induk fungsi, namanya, dan seterusnya.

Fitur yang Didukung

API pembuatan profil menyediakan informasi tentang berbagai peristiwa dan tindakan yang terjadi dalam runtime bahasa umum. Anda dapat menggunakan informasi ini untuk memantau cara kerja proses dan menganalisis performa aplikasi .NET Framework Anda.

API pembuatan profil mengambil informasi tentang tindakan dan peristiwa berikut yang terjadi di CLR:

  • Peristiwa mulai dan matikan CLR.

  • Pembuatan domain aplikasi dan peristiwa penonaktifan.

  • Peristiwa pemuatan dan pembongkaran perakitan.

  • Peristiwa pemuatan dan pembongkaran modul.

  • Peristiwa pembuatan dan penghancuran COM vtable.

  • Kompilasi just-in-time (JIT) dan peristiwa peluncuran kode.

  • Peristiwa pemuatan dan pembongkaran kelas.

  • Peristiwa pembuatan dan penghancuran rangkaian.

  • Peristiwa entri fungsi dan keluar.

  • Pengecualian.

  • Transisi antara eksekusi kode terkelola dan tidak terkelola.

  • Transisi antara konteks runtime yang berbeda.

  • Informasi tentang penangguhan runtime.

  • Informasi tentang tumpukan memori runtime dan aktivitas pengumpulan sampah.

API pembuatan profil dapat dipanggil dari bahasa apa pun yang kompatibel dengan COM (tidak terkelola).

API ini efisien sehubungan dengan konsumsi CPU dan memori. Pembuatan profil tidak melibatkan perubahan pada aplikasi yang diprofilkan yang cukup signifikan untuk menyebabkan hasil yang menyesatkan.

API pembuatan profil berguna untuk pembuat profil pengambilan sampel dan profiler non-sampling. Profiler pengambilan sampel memeriksa profil pada detak jam biasa, katakanlah, pada jarak 5 milidetik. Profiler non-sampling diberi tahu tentang suatu peristiwa secara sinkron dengan rangkaian yang menyebabkan peristiwa tersebut.

Fungsionalitas yang Tidak Didukung

API pembuatan profil tidak mendukung fungsi berikut:

  • Kode tidak terkelola, yang harus diprofilkan menggunakan metode Win32 konvensional. Namun, profiler CLR menyertakan peristiwa transisi untuk menentukan batas antara kode yang dikelola dan tidak dikelola.

  • Aplikasi yang memodifikasi sendiri yang memodifikasi kode mereka sendiri untuk tujuan seperti pemrograman berorientasi aspek.

  • Pemeriksaan batas, karena API pembuatan profil tidak menyediakan informasi ini. CLR menyediakan dukungan intrinsik untuk pemeriksaan batas semua kode yang dikelola.

  • Pembuatan profil jarak jauh, yang tidak didukung karena alasan berikut:

    • Pembuatan profil jarak jauh memperpanjang waktu eksekusi. Saat Anda menggunakan antarmuka pembuatan profil, Anda harus meminimalkan waktu eksekusi sehingga hasil pembuatan profil tidak akan terlalu terpengaruh. Ini terutama berlaku saat performa eksekusi sedang dipantau. Namun, pembuatan profil jarak jauh bukanlah batasan ketika antarmuka pembuatan profil digunakan untuk memantau penggunaan memori atau untuk mendapatkan informasi run-time tentang bingkai tumpukan, objek, dan sebagainya.

    • Profiler kode CLR harus mendaftarkan satu atau beberapa antarmuka panggilan balik dengan runtime di komputer lokal tempat aplikasi yang diprofilkan sedang berjalan. Ini membatasi kemampuan untuk membuat profiler kode jarak jauh.

Rangkaian Pemberitahuan

Dalam kebanyakan kasus, rangkaian yang menghasilkan suatu peristiwa juga mengeksekusi pemberitahuan. Pemberitahuan tersebut (misalnya, FunctionEnter dan FunctionLeave) tidak perlu menyediakan ThreadID eksplisit. Selain itu, profiler mungkin memutuskan untuk menggunakan penyimpanan lokal rangkaian untuk menyimpan dan memperbarui blok analisisnya alih-alih mengindeks blok analisis dalam penyimpanan global, berdasarkan ThreadID rangkaian yang terpengaruh.

Perhatikan bahwa panggilan balik ini tidak diserialisasikan. Pengguna harus melindungi kode mereka dengan membuat struktur data yang aman untuk rangkaian dan dengan mengunci kode profiler jika diperlukan untuk mencegah akses paralel dari beberapa rangkaian. Oleh karena itu, dalam kasus tertentu Anda dapat menerima urutan panggilan balik yang tidak biasa. Misalnya, asumsikan bahwa aplikasi terkelola menelurkan dua rangkaian yang mengeksekusi kode identik. Dalam hal ini, dimungkinkan untuk menerima peristiwa ICorProfilerCallback::JITCompilationStarted untuk beberapa fungsi dari satu rangkaian dan FunctionEnter panggilan balik dari rangkaian lainnya sebelum menerima panggilan balik ICorProfilerCallback::JITCompilationFinished. Dalam hal ini, pengguna akan menerima panggilan balik FunctionEnter untuk fungsi yang mungkin belum sepenuhnya dikompilasi just-in-time (JIT).

Keamanan

DLL profiler adalah DLL tidak terkelola yang berjalan sebagai bagian dari mesin eksekusi runtime bahasa umum. Akibatnya, kode di profiler DLL tidak patuh pada pembatasan keamanan akses kode terkelola. Satu-satunya batasan pada profiler DLL adalah yang dikenakan oleh sistem operasi pada pengguna yang menjalankan aplikasi yang diprofilkan.

Penulis profiler harus mengambil tindakan pencegahan yang tepat untuk menghindari masalah terkait keamanan. Misalnya, selama penginstalan, profiler DLL harus ditambahkan ke daftar kontrol akses (ACL) sehingga pengguna yang berbahaya tidak dapat mengubahnya.

Menggabungkan Kode Terkelola dan Tidak Terkelola dalam Profiler Kode

Profiler yang salah ditulis dapat menyebabkan referensi melingkar itu sendiri, yang mengakibatkan perilaku yang tidak terduga.

Peninjauan CLR API pembuatan profil dapat membuat kesan bahwa Anda dapat menulis profiler yang berisi komponen terkelola dan tidak terkelola yang saling memanggil melalui interop COM atau panggilan tidak langsung.

Meskipun ini dimungkinkan dari perspektif desain, API pembuatan profil tidak mendukung komponen terkelola. Profiler CLR harus benar-benar tidak dikelola. Upaya untuk menggabungkan kode terkelola dan tidak terkelola dalam profiler CLR dapat menyebabkan pelanggaran akses, kegagalan program, atau kebuntuan. Komponen yang dikelola profiler akan mengaktifkan peristiwa kembali ke komponen yang tidak dikelola, yang selanjutnya akan memanggil komponen yang dikelola lagi, menghasilkan referensi melingkar.

Satu-satunya lokasi di mana profiler CLR dapat memanggil kode terkelola dengan aman adalah dalam isi bahasa perantara umum (CIL) metode. Praktik yang direkomendasikan untuk memodifikasi isi CIL adalah menggunakan metode kompilasi ulang JIT di antarmuka ICorProfilerCallback4 .

Dimungkinkan juga untuk menggunakan metode instrumentasi yang lebih lama untuk memodifikasi CIL. Sebelum kompilasi fungsi just-in-time (JIT) selesai, profiler dapat menyisipkan panggilan terkelola dalam isi CIL metode lalu mengkompilasinya (lihat metode ICorProfilerInfo::GetILFunctionBody ). Teknik ini dapat berhasil digunakan untuk instrumentasi selektif dari kode yang dikelola, atau untuk mengumpulkan statistik dan data performa tentang JIT.

Atau, profiler kode dapat memasukkan kait asli ke dalam isi CIL dari setiap fungsi terkelola yang memanggil ke dalam kode yang tidak dikelola. Teknik ini dapat digunakan untuk instrumentasi dan cakupan. Misalnya, profiler kode dapat menyisipkan kait instrumentasi setelah setiap blok CIL untuk memastikan bahwa blok telah dijalankan. Modifikasi tubuh CIL dari metode adalah operasi yang sangat halus, dan ada banyak faktor yang harus dipertimbangkan.

Pembuatan Profil Kode Tidak Terkelola

Runtime bahasa umum (CLR) API pembuatan profil menyediakan dukungan minimal untuk membuat profil kode yang tidak dikelola. Fungsionalitas berikut disediakan:

  • Enumerasi tautan tumpukan. Fitur ini memungkinkan profiler kode untuk menentukan batas antara kode yang dikelola dan kode tak terkelola.

  • Penentuan apakah rantai tumpukan sesuai dengan kode terkelola atau kode asli.

Dalam .NET Framework versi 1.0 dan 1.1, metode ini tersedia melalui subset dalam proses dari API penelusuran kesalahan CLR. Mereka didefinisikan dalam file CorDebug.idl.

Dalam .NET Framework 2.0 dan yang lebih baru, Anda dapat menggunakan metode ICorProfilerInfo2::DoStackSnapshot untuk fungsi ini.

Menggunakan COM

Meskipun antarmuka pembuatan profil didefinisikan sebagai antarmuka COM, runtime bahasa umum (CLR) sebenarnya tidak menginisialisasi COM untuk menggunakan antarmuka ini. Alasannya adalah untuk menghindari keharusan mengatur model rangkaian dengan menggunakan fungsi CoInitialize sebelum aplikasi terkelola memiliki kesempatan untuk menentukan model rangkaian yang diinginkan. Demikian pula, profiler itu sendiri tidak boleh memanggil CoInitialize, karena mungkin dapat memilih model rangkaian yang tidak kompatibel dengan aplikasi yang sedang diprofilkan dan yang dapat menyebabkan kegagalan aplikasi.

Tumpukan Panggilan

API pembuatan profil menyediakan dua cara untuk mendapatkan tumpukan panggilan: metode snapshot tumpukan, yang memungkinkan pengumpulan tumpukan panggilan yang jarang, dan metode tumpukan bayangan, yang melacak tumpukan panggilan setiap saat.

Snapshot Tumpukan

Snapshot tumpukan adalah jejak tumpukan rangkaian secara instan. API pembuatan profil mendukung pelacakan fungsi terkelola di tumpukan, tetapi membiarkan penelusuran fungsi yang tidak dikelola ke tumpukan walker profiler itu sendiri.

Untuk informasi selengkapnya tentang cara memprogram profiler untuk menjalankan tumpukan terkelola, lihat metode ICorProfilerInfo2::DoStackSnapshot dalam kumpulan dokumentasi ini, dan Tumpukan Profiler Berjalan .NET Framework 2.0: Dasar dan Di Atasnya.

Tumpukan Bayangan

Menggunakan metode snapshot terlalu sering dapat dengan cepat menimbulkan masalah performa. Jika Anda ingin sering melakukan pelacakan tumpukan, profiler Anda harus membuat tumpukan bayangan dengan menggunakan FunctionEnter2, FunctionLeave2, FunctionTailcall2, dan ICorProfilerCallback2 panggilan balik pengecualian. Tumpukan bayangan selalu terkini dan dapat dengan cepat disalin ke penyimpanan kapan pun snapshot tumpukan diperlukan.

Tumpukan bayangan dapat memperoleh argumen fungsi, nilai yang dikembalikan, dan informasi tentang instantiasi umum. Informasi ini hanya tersedia melalui tumpukan bayangan dan dapat diperoleh ketika kontrol diserahkan ke suatu fungsi. Namun, informasi ini mungkin tidak tersedia nanti selama menjalankan fungsi.

Panggilan Balik dan Kedalaman Tumpukan

Callback profiler dapat dikeluarkan dalam keadaan yang sangat dibatasi tumpukan, dan luapan tumpukan dalam panggilan balik profiler akan menyebabkan proses keluar dengan segera. Profiler harus memastikan untuk menggunakan tumpukan sesedikit mungkin sebagai respons terhadap panggilan balik. Jika profiler dimaksudkan untuk digunakan terhadap proses yang kuat terhadap tumpukan luapan, profiler itu sendiri juga harus menghindari pemicu luapan tumpukan.

Judul Deskripsi
Menyiapkan Lingkungan Pembuatan Profil Menjelaskan cara menginisialisasi profiler, mengatur pemberitahuan peristiwa, dan memprofilkan Layanan Windows.
Antarmuka Pembuatan Profil Menjelaskan antarmuka tidak terkelola yang digunakan API pembuatan profil.
Pembuatan Profil Fungsi Statis Global Menjelaskan fungsi statik global tidak terkelola yang digunakan API pembuatan profil.
Enumerasi Pembuatan Profil Menjelaskan enumerasi tidak terkelola yang digunakan API pembuatan profil.
Struktur Pembuatan Profil Menjelaskan struktur tidak terkelola yang digunakan API pembuatan profil.