Görev yöneticisinin bellek sekmesinde, sağ alt köşede yer alan bir "disk belleği olmayan havuz" (non paged pool) bölümü var. Bu bölüm, kullanıcı bellek harcamalarının dışında sürücü ve sistem bileşenlerinin kullandığı ve hiçbir zaman diske (sanal bellek) yazılmayacak miktarı gösterir.
Ekran görüntüleri, benim yaşadığım sorunlu bilgisayara ait değil.
Bu değerin normal bir bilgisayarda 300-400 MB civarında olması beklenir. Ama bir bilgisayarda bu 1,6 GB'ı bulmuştu. Bu bir bellek sızıntısı (memory leak) mı? Bir sürücü işletim sisteminden sürekli bellek talep edip, bunları hiçbir zaman boşaltmazsa bellek sızıntısı olur. İncelemek gerek.
Bu tür durumlarda poolmon kullanılabilir. Bu araç, sürücülerin diske yazılmayan bellek kullanımlarını inceler. Her alanın doğrudan hangi bileşen/süreç tarafından kullanıldığını görmek mümkün değil, ama talep edilen alanlar için bir etiket kullanılır. Bu etiketten şişkin alanın hangi bileşen/süreç ile ilgili olduğu bulunabilir. Poolmon'u indirmek için Windows Driver Kit'i indirmek gerek. Bu kit, başka bileşenlerle de gelir. wdksetup.exe'yi çalıştırdıktan sonra buna göre seçenekleri işaretlemek gerek.
WDK ile birlikte poolmon'u kurduktan sonra çalıştırınca (komut satırından) aşağıdaki gibi bir çıktı verir.
Sütunları inceleyelim.
Tag: Etiket. Alanın hangi sürücü ile ilgili olduğunun anlaşılmasını kolaylaştırmak için.
Type: Rezervasyon tipi. Paged (diske yazılabilecek şekilde rezerve edilen bellek alanı) veya Nonp (diske yazılmayacak şekilde rezerver edilen bellek alanı). Benim durumum için önemli olan alanlar Nonp olanlar.
Allocs: Bellek talep sayısı. Kaç kez rezervasyon yapıldığını gösteriyor.
Frees: Kaç kez rezerve edilen alanların serbest bıraklıdığını (işletim sistemine iade) gösteriyor.
Diff: Allocs ve Frees arasındaki fark; yani rezerve edilip henüz serbest bırakılmamış alan sayısı. Dikkat, miktar değil.
Bytes: İlgili etiketin toplam aktif kullandığı diske yazılmayan bellek alanı.
Per Alloc: Yapılan işlemlerin ortalaması.
Benim durumum için "b"ye basarak Bytes alanına göre sıralamak faydalı oldu. Bazı klavye kısayolları:
e : Pencerenin altında toplamları göster/gizle (varsayılan kapalı)
a : Allocs alanına göre sırala
f : Frees alanına göre sırala
d : Diffs alanına göre sırala
m : Per Allocs alanına göre sırala
b : Bytes alanına göre sırala
Peki bunu gördük, ne yapabiliriz? Elimizden çok fazla şey gelmiyor. Yapılabilecek şeyler, görüntülenen etiketin hangi sürücüye ait olduğunu bulmak, sonrasında bu sürücüyü güncellemek ve güncel sürücünün bellek sızıntısı yapmayacağını ummak.
Benim durumumda görüntülenen etiket, ismc'ydi. Bu da Intel Rapid Store Technology (RST) ile ilgiliydi. Sorun çözme adımları olarak önce ilgili event tracing'i bilgisayar açıldıktan sonra devre dışı bıraktım.
logman stop IntelRST -ets
ETW içindeki veri kaynaklarını inceledim.
logman query -ets
Intel ile ilgili sürücüleri listeledim
driverquery /v | findstr /i
Hiç biri faydalı olmadı. Aynı sorundan şikayetçi kaç kişi var acaba?
İçinde ismc etiketi geçen sürücüleri aramak için şöyle bir komut önerilmiş.
findstr /m /s /l ismc *.sys
Bu aslında metin dosyalarının içinde ismc anahtar kelimesini arayan bir komut. Bunun powershell eşdeğerini denemek istedim.
dir *.sys -rec -ea silent | sls ismc | select path
Konuyu biraz saptırdım ama yukarıdaki eşdeğer, asıl komuttan daha fazla sayıda çıktı üretti. Bunun sebebi findstr'nin unicode desteğinin olmaması. sls (Select-String) unicode desteğine sahip olduğu için daha fazla dosya bulur.
Daha ileri seviye bir teknik için, superuser.com üzerinde 2015'te sorulan şu soruya magicandre1981 tarafından verilen cevap incelenebilir.
Uzak bir bilgisayardaki "disk belleği olmayan havuz" değerine ulaşmak istedim. Bunun için iki seçenek var. Performans sayaçları (performance counters) ve WMI (ya da yeni adıyla CIM) sorguları.
Performans sayaçları konusu biraz karışık. Dile göre farklılık gösterebiliyor. Örnek olarak uzak bilgisayar İngilizce yerelleştirmeye sahipse bu sayaç değerini okumak için.
(Get-Counter -Computername uzakpc "\Memory\Pool Nonpaged Bytes").CounterSamples.CookedValue
yeterli olurken, Türkçe bir bilgisayarda
(Get-Counter -Computername uzakpc "\Bellek\disk belleği olmayan havuz bayt sayısı").CounterSamples.CookedValue
çalışmadı. Onun yerine terminalden
Invoke-Command -Computername uzakpc {Get-Counter "\Bellek\disk belleği olmayan havuz bayt sayısı").CounterSamples.CookedValue}ile sonuca ulaştım. Ancak bu satırı kopyalayıp bir metin dosyasına kaydedip ps1 uzantılı bir betik dosyası oluşturduğumda aldığım hata
Internal performance counter API call failed. Error: c0000bb9.
+ CategoryInfo : InvalidResult: (:) [Get-Counter], Exception
+ FullyQualifiedErrorId : CounterApiError,Microsoft.PowerShell.Commands.GetCounterCommand
+ PSComputerName : uzakpc oldu. Bir sorun var. O da dosyayı UTF-8 olarak kaydetmek. Kodlamayı ANSI olarak değiştirince sorun çözüldü. Şu sayfada powershell'in ps1 dosyalarında UTF-8 kodlamasını da kabul ettiği, sorunun sadece bazı karakterlerin kopyala yapıştır sırasında yanlış yerleştirildiğinden bahsedilmiş. Bu konu henüz incelenmedi.
İkinci yöntem olarak CIM sorgusu ile de ilerleyebilirdim.
(Get-CIMInstance -Computername uzakpc Win32_PerfFormattedData_PerfOS_Memory).PoolNonpagedBytes
Ama ilginç bir şekilde ilk kullanımda bu değeri dönmesi uzun sürüyor (+1 dakika).
---
https://woshub.com/huge-memory-usage-non-paged-pool-windows/
https://community.intel.com/t5/Rapid-Storage-Technology/Non-Paged-pool-memory-usage-too-high/m-p/1243440
https://www.tenforums.com/performance-maintenance/101582-very-high-ram-usage-all-time-w10.html
https://community.intel.com/t5/Rapid-Storage-Technology/Non-Paged-pool-unusually-high-ismc-non-paged-pool/td-p/1288935
https://www.tenforums.com/performance-maintenance/168382-high-ram-usage-non-paged-pool-size.html

