Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
.NET 8'den .NET 11'e Diagnostics'te Değişenler: System.Runtime Meter, Yeni dotnet-trace Profile'ları, collect-linux, Runtime Async Stack'leri ve In-Process Crash Report
.NET 9 eski EventCounter'ları System.Runtime Meter'ıyla değiştirdi, .NET 10 dotnet-trace'in varsayılanlarını ve collect-linux'u getirdi, .NET 11 ise kayıpsız event tamponu, runtime async ve process içi crash report ekledi. Eski ve yeni metric adlarının eşleme tablosunu veriyor, cpu-sampling ve Block modu hatalarını, runtime async'in askıya alma öncesi ve sonrası stack'lerini ve crash report çıktısını .NET 10 ve 11'de gerçek koşularla gösteriyoruz.
Diagnose, Fix, Prove: Bookstore'da Uçtan Uca Bir Performans Vakası
Bir performans sorununu çözmenin yolu sırayla ölçmek: dotnet-counters ile geniş bakış, dotnet-trace ile sıcak yol, gcdump ile büyüyen tip, sonra BenchmarkDotNet ve aynı yükle k6 ile kanıt. Bookstore checkout'unun p99'unu 537 ms'ye çıkaran kök nedeni, kod incelemesinin suçladığı yeni JsonSerializerOptions değil, her istekte 2.000 kuralı okumak ve hiç hit almayan bir cache olarak buluyor, düzeltmeyle p99'u 1,5 ms'ye indiriyor ve bir rapor şablonu veriyoruz.
Production'da Diagnostics: dotnet-monitor, Collection Rule'lar, Kubernetes Sidecar ve Continuous Profiling
dotnet-monitor, trace, gcdump ve dump'ı kimsenin container'a girmesine gerek bırakmadan bir HTTP API ve collection rule'larla toplar; rule'lar için Listen modu, güvenlik için localhost'a bağlı API, API key ve sınırlı egress gerekir. Bookstore'u kind'de sidecar'la çalıştırıyor, yavaş rapor isteklerinde ve kendi meter'ımızda tetiklenen kuralları, Limits'in throttling'ini ve suspend/nosuspend farkını ölçüyor, OpenTelemetry Profiles'ın alpha durumuna bakıyoruz.
Visual Studio ve Rider Profiler'ları: CPU Usage, .NET Object Allocation, Instrumentation, Database ve Async Araçları
IDE profiler'ları geliştirici makinesinde en hızlı sonucu verir; Visual Studio'nun Database aracı N+1'i aynı metinli yüzlerce kısa sorgu olarak gösterir. Bookstore'un Siparişlerim sayfasında lazy loading'in istek başına 80 SQL komutu gönderdiğini ve thread pool'u tıkadığını aynı event'leri komut satırından okuyarak ölçüyor, Include ile throughput'u 30, projection ile 41 katına çıkarıyor; Copilot Profiler Agent'ı ve Rider'ın dotTrace/dotMemory karşılıklarını konumlandırıyoruz.
PerfView ile Derin Analiz: GC Stats, JIT Stats, Grouping/Folding ve İki Trace'i Karşılaştırmak
PerfView'in gücü GroupPats, Fold%, diff ve GCStats/JITStats raporlarında; hepsi TraceEvent kütüphanesine dayandığı için aynı analizi Linux'ta kodla da yapabilirsin. Bookstore'da iki trace'i diff'leyerek bir regresyonun 2,6 saniyesinin GC beklemesi olduğunu buluyor, JITStats ile ReadyToRun'ın açılışta JIT'lenen method'ları yalnızca 980'den 928'e indirdiğini ölçüyor ve CI için gürültüsü ölçülmüş bir allocation kapısı kuruyoruz.
Memory Leak Avı: dotnet-gcdump, Heap Snapshot Karşılaştırma ve Yaygın Leak Pattern'leri
Memory leak tek snapshot'la değil, aynı yükte alınan iki gcdump'ın farkıyla ve büyüyen object'i kökten tutan retention path'le bulunur. Bookstore'da singleton bir event'e abone olup hiç ayrılmayan scoped handler'ın 20.000 istekte heap'i 17,8 MB'tan 348,5 MB'a çıkarmasını dotnet-gcdump ile yakalıyor, gcdump'ı full dump'la karşılaştırıyor, düzeltmeyi üçüncü snapshot'la kanıtlıyor ve yaygın leak pattern'lerini listeliyoruz.
Allocation ve GC Analizi: gc-verbose, Allocation Sampling, LOH ve Server GC/DATAS Ayarları
GC sorunu sık gen2, yüksek pause oranı ve büyüyen LOH ile kendini gösterir; çözümü GC ayarında değil allocation'ı azaltmakta aranır. Bookstore'un CSV export'unda istek başına 60 MB allocation'ı gc-verbose ve .NET 10'un allocation sampling'iyle stack'e bağlıyor, streaming ve ArrayPool ile 115 KB'a indiriyor, Server GC, DATAS ve Workstation GC'yi aynı yükte karşılaştırıyor ve container limitinin GCHeapHardLimit'e etkisini gösteriyoruz.
CPU Profiling: dotnet-trace ile Flame Graph Okumak, Sampled Thread Time ve Linux'ta collect-linux
dotnet-trace'in varsayılan profile'ı CPU değil duvar saati örnekler; bu yüzden topN listesinin başında bekleyen thread'ler olur ve sıcak noktayı flame graph'ta istek thread'lerine bakarak bulursun. Bookstore'un arama endpoint'inde her istekte derlenen Regex'i speedscope'ta bulup [GeneratedRegex] ve projection ile düzeltiyor, istek başına CPU'yu 1,87 ms'den 0,07 ms'ye indiriyor ve collect-linux'un şartlarını gerçek hatalarla gösteriyoruz.
dotnet-counters ve Built-in Metric'ler: System.Runtime Meter'ı, ASP.NET Core/Kestrel Metric'leri ve Kendi Meter'ın
dotnet-counters ilk bakış aracıdır: .NET 9+ System.Runtime Meter'ı GC, JIT, thread pool ve CPU'yu, ASP.NET Core meter'ları istek sürelerini yüzdelikleriyle gösterir. Kümülatif ve anlık metric farkını, .NET 8'deki eski EventCounter isimlerini, IMeterFactory ile kendi Meter'ını yazmayı ve collect ile CSV baseline almayı Bookstore'da gerçek yük altında anlatıyoruz; baseline, CPU'nun üçte birini yiyen JIT'i ortaya çıkarıyor.
.NET Diagnostics Haritası: Hangi Soruya Hangi Araç? EventPipe, Diagnostic Port ve Güvenli Toplama
Araç seçimi sorudan başlar: bir şey ters mi diye dotnet-counters, zaman nereye gidiyor diye dotnet-trace, bellekte ne kalıyor diye dotnet-gcdump, process'in tam hâli için dotnet-dump. EventPipe, ETW ve Linux'ta user_events farkını, diagnostic port'un TMPDIR ve kullanıcı şartını, container'da sidecar'ı, dnx ve tool manifest ile kurulumu, trace'in gerçek overhead'ini ve dosya boyutunu Bookstore lab'ında ölçüyoruz.
DevTools ve AI: Gemini AI Assistance, Chrome DevTools MCP ve Recorder
Chrome DevTools MCP server'ı coding agent'a tarayıcıdaki her şeyi açar: ayrı profil, --no-usage-statistics ve --no-performance-crux olmadan kişisel oturumların ve URL'lerin dışarı çıkabilir. Agent'la /books/abc'de SPA fallback'inin API'ye HTML döndürdüğü ve NaN IndexedDB key'i hatalarını source-mapped stack'lerle bulup düzeltiyoruz; Gemini AI assistance'ın şartları, DevToolsGenAiSettings policy'si ve Recorder kaydını Puppeteer'a aktarmak.
Angular DevTools: Component Tree, Profiler, Injector Tree ve Router Tree
Angular DevTools yalnız development build'de çalışır ve optimization: false ile alınan build de development modunda davranır: Service Worker kapanır, budget'lar aşılır. Components, Signal Graph, Profiler, Injector Tree ve Router Tree'yi gerçek verilerle okuyoruz: NG0201 hatasını route seviyesinde provider ile çözüp yeni Route: reviews injector'ını görmek ve OnPush'ta track book.id ile kart template güncellemelerinin 855'ten 0'a inmesi.