Özel bayt, sanal bayt, çalışma kümesi nedir?


490

Bir süreçte bellek sızıntıları hata ayıklamak için perfmon windows yardımcı programını kullanmaya çalışıyorum.

Perfmon terimleri şöyle açıklar:

Çalışma Kümesi , bu işlemin Çalışma Kümesinin bayt cinsinden geçerli boyutudur. Çalışma Kümesi, işlemdeki iş parçacıklarının son zamanlarda dokunduğu bellek sayfaları kümesidir. Bilgisayardaki boş bellek bir eşiğin üzerindeyse, sayfalar kullanılmasa bile bir işlemin Çalışma Kümesinde kalır. Boş bellek bir eşiğin altına düştüğünde, sayfalar Çalışma Kümelerinden kesilir. İhtiyaç duyulursa, ana bellekten ayrılmadan önce Çalışma Setine yumuşak bir şekilde arızalanırlar.

Sanal Bayt , işlemin kullandığı sanal adres alanının geçerli bayt cinsinden boyutudur. Sanal adres alanının kullanılması, disk veya ana bellek sayfalarının karşılık gelen kullanımı anlamına gelmez. Sanal alan sonludur ve süreç kütüphaneleri yükleme yeteneğini sınırlayabilir.

Özel Bayt , bu işlemin ayırdığı ve diğer işlemlerle paylaşılamayan belleğin geçerli bayt cinsinden boyutudur.

Sorularım:

İşlemin herhangi bir paylaşılan kitaplık içermediğinden herhangi bir sızıntı olup olmadığını kontrol etmek için ölçmem gereken Özel Baytlar mı ve eğer olursa, herhangi bir sızıntı sürecin kendisinden mi gelecek?

İşlem tarafından tüketilen toplam bellek nedir? Sanal Bayt mı yoksa Sanal Bayt ve Çalışma Kümesinin toplamı mı?

Özel Baytlar, Çalışma Kümesi ve Sanal Baytlar arasında herhangi bir ilişki var mı?

Bellek kullanımı hakkında daha iyi bir fikir veren başka araçlar var mı?


3
Daha iyi bir araç valgrind / helgrind olurdu, ancak ne yazık ki Windows altında değil :(
Kornel Kisielewicz

O özel bayt ben işlemi herhangi sızıntısı yaşıyor emin eğer olmak ölçmek gerekir mi Eğer özel bayt bir sürecin ardından büyümez hiçbir bellek sızıntısı var. Eğer büyürlerse bunun nedeni bellek sızıntıları olabilir ve bunun nedeni bellek parçalanması olabilir. Özel baytların büyümesine tam olarak ne anlama geldiğini söylemek zor .

@SergeiKurenkov Söyleyebileceğimiz bir şey, ASLA "bellek parçalanması" ndan kaynaklanmayacağıdır.
Jamie Hanrahan

Yanıtlar:


517

Bu sorunun kısa cevabı , bu değerlerin hiçbirinin bir yürütülebilir dosyanın gerçekten ne kadar bellek kullandığının güvenilir bir göstergesi olmadığı ve hiçbirinin bir bellek sızıntısını ayıklamak için gerçekten uygun olmadığıdır.

Özel Baytlar , işlem yürütülebilir dosyasının istediği bellek miktarını ifade eder - gerçekte kullandığı miktarı değil . Bunlar "özel" dir, çünkü (genellikle) bellek eşlemeli dosyaları (yani paylaşılan DLL dosyaları) hariç tutarlar. Ancak - işte yakalama - bu dosyalar tarafından ayrılan belleği mutlaka dışlamazlar . Özel baytlardaki bir değişikliğin yürütülebilir dosyanın kendisinden mi yoksa bağlantılı bir kitaplıktan mı kaynaklandığını anlamanın bir yolu yoktur. Özel baytlar da sadece fiziksel bellek değildir ; diske veya bekleme sayfası listesinde (sayfa artık kullanılmamaktadır, ancak henüz sayfalandırılmamıştır) sayfalanabilirler.

Çalışma Kümesi , işlem tarafından kullanılan toplam fiziksel belleği (RAM) ifade eder . Bununla birlikte, özel baytlardan farklı olarak, bu, bellek eşlemeli dosyalar ve diğer çeşitli kaynakları da içerir, bu nedenle özel baytlardan daha da hassas bir ölçümdür. Bu, Görev Yöneticisi'nin "Mem Usage" bölümünde bildirilen değerle aynıdır ve son yıllarda sonsuz miktarda kafa karışıklığı kaynağı olmuştur. Çalışma Kümesindeki bellek, bir sayfa hatası olmadan adreslenebilmesi bakımından "fiziksel" dir; Ancak bekleme sayfa listesi de hala fiziksel olarak hafızada ancak çalışma kümesinin bildirilen ve bir uygulamayı minimize aniden bırak "Mem Kullanımı" ibaresini görebilirsiniz nedeni budur.

Sanal Baytlar , tüm işlem tarafından kullanılan toplam sanal adres alanıdır . Bu, bellek eşlemeli dosyalar (paylaşılan DLL'ler) içerdiği için çalışma kümesine benzer, ancak bekleme listesindeki verileri ve zaten disk belleği olan ve diskteki bir sayfa dosyasında oturan verileri de içerir. Ağır yük altındaki bir sistemdeki her işlem tarafından kullanılan toplam sanal bayt, makinenin sahip olduğundan önemli ölçüde daha fazla bellek ekleyecektir.

Yani ilişkiler:

  • Özel Baytlar, uygulamanızın gerçekten ayırdığı şeydir, ancak sayfa dosyası kullanımını içerir;
  • Çalışma Kümesi, disk belleği olmayan Özel Baytlar artı bellek eşlemeli dosyalardır;
  • Sanal Baytlar Çalışma Kümesi artı sayfalandırılmış Özel Baytlar ve bekleme listesidir.

Burada başka bir sorun daha var; Paylaşılan kütüphanelerin uygulama modülünüzde bellek ayırabilmesi ve uygulamanızın Özel Baytlarında bildirilen olası yanlış pozitiflere yol açması gibi , uygulamanız da paylaşılan modüllerin içinde bellek tahsis edebilir ve bu da yanlış negatiflere yol açabilir . Bu, uygulamanızın Özel Baytlarda hiç kendini göstermeyen bir bellek sızıntısına sahip olmasının mümkün olduğu anlamına gelir. Olası değil, ama mümkün.

Özel Baytlar, yürütülebilir dosyanızın kullandığı bellek miktarına makul bir yaklaşımdır ve bellek sızıntısı için olası adayların bir listesini daraltmaya yardımcı olmak için kullanılabilir ; sayının sürekli ve sonsuz bir şekilde büyüdüğünü ve büyüdüğünü görürseniz, bu süreci bir sızıntı açısından kontrol etmek istersiniz. Ancak bu, bir sızıntı olduğunu ya da olmadığını kanıtlayamaz .

Windows'da bellek sızıntılarını tespit etmek / düzeltmek için en etkili araçlardan biri aslında Visual Studio'dur (bağlantı, ürün sayfası için değil, bellek sızıntıları için VS'yi kullanma sayfasına gider). Rasyonel Arındırmak başka bir olasılıktır. Microsoft ayrıca bu konuda daha genel bir en iyi uygulamalar belgesine sahiptir . Bu önceki soruda listelenen daha fazla araç var .

Umarım bu birkaç şeyi temizler! Bellek sızıntılarını takip etmek, hata ayıklamada yapılması en zor şeylerden biridir. İyi şanslar.


26
Korkarım cevap vermen doğru değil. Özel Bayt, yalnızca yürütülebilir bellek değil, işlem yürütülebilir dosyasının istediği bellek miktarını (RAM) ifade eder. Böylece, özel baytları izleyerek bellek sızıntısı durumlarının çoğunu mutlaka inceleyebilirsiniz. :: VisualAlloc'u büyük bir bellek yığını (1.5G diyelim) için deneyin. Özel baytlarınızın çalışma kümesinden çok daha büyük olduğunu görebilmeniz gerekir. Bu, "Çalışma Kümeniz Özel Bayt artı Bellek eşlemeli dosyalar" ın hatalı olduğunu kanıtlar.
Jay Zhu

4
Aslında, yazma anlayışının "Çalışma Kümesi bellek içi Özel Baytlar artı Bellek eşlemeli dosyalardır" olduğuna inanıyorum. Ve Özel Baytlar değiştirilemez - makinedeki fiziksel bellekten daha büyük özel baytları görebilirsiniz.
Jay Zhu

2
@Aaronaught: Güvenilir gösterge ve hata ayıklamaya uygun ilk ifadeniz kafa karıştırıcı. Özel baytlar, uygulamanın bellek alanında sızıntı olduğunu gösteren güvenilir bir göstergedir. Bağımlı bir DLL ve dolaylı olabilir, ancak uygulama bellek alanında bir sızıntıdır. Hata ayıklama için neden kullanılamadığını açıklayabilir misiniz? Uygulama sürecinin tam bir bellek dökümü, bu belleği neyin tükettiğini bize bildirmelidir. Hata ayıklama için neden kullanılamayacağını anladığımdan emin değilim. Biraz ışık tutabilir misin?
G33kKahuna

@ G33kKahuna: Bana göre bir bellek dökümü hafızayı anlamlı bir şekilde neyin tükettiğini nasıl anlatacak belli değil - "ne" demek istediğiniz "hangi modülleri kastediyorsunuz, ama sonra sahip olduğunuz tek şey bir anlık görüntü hangi modül zaman içinde ve sıkı kontrollü koşullar altında birkaç çöplük atmazsanız zaman içinde gerçekten bellek sızdırıyor. Daha verimsiz ve güvenilir olmayan bir hata ayıklama stratejisi bulmak zor. Profilciler bugünlerde her yerde; birini kullanın.
Aaronaught

1
Bir tam! Objsize çalıştırın, bu hemen yığıntaki sabitlenmiş nesneleri göstermelidir. Eeheap -gc öğesini kontrol ederek onaylayabilirsiniz. Bu, birimin nerede sıkıştığını göstermelidir. Tipik olarak, yukarıdaki komutların hepsinde ipucu yoksa, özel baytlarınız GC'deki toplanmamış nesneler tarafından tüketilir. Şimdi gchandles veya gcleaks'e geçin. Bu komutlar size hangi türlerin / nesne adreslerinin eşlenemeyeceğini söylemelidir. İşaretçi hala orada ama nesne gitti. Bu, yayınlanmamış olay işleyicileri için böyle kategorik bir sorundur.
G33kKahuna

10

Bellek sızıntılarını belirlemek için perfmon, görev yöneticisi veya benzeri bir araç kullanmaya çalışmamalısınız. Eğilimleri belirlemek için iyidirler, ancak başka bir şey değildir. Mutlak terimlerle bildirdikleri sayılar, bellek sızıntısı algılama gibi belirli bir görev için yararlı olamayacak kadar belirsiz ve toplanmıştır.

Bu soruya daha önce verilen bir cevap, çeşitli türlerin ne olduğuna dair büyük bir açıklama yaptı.

Bir araç önerisi soruyorsunuz: Bellek Doğrulayıcı'yı öneriyorum. Milyarlarca bellek ayırma yapan uygulamaları izleme yeteneğine sahiptir.

http://www.softwareverify.com/cpp/memory/index.html

Feragatname: Bellek Doğrulayıcı'yı tasarladım.


1
Basit bir sınıf dosyasını bile çalıştıramıyorum (Java'da)? Ne oluyor?
jn1kk

Stephen ve Devil'in bir şekilde ilişkili veya hatta klonlandığından şüpheleniyorum ...: D;)
Robert Koritnik

@StephenKellett, Deneme sürümü var mı?
Pacerier

@Pacerier, bağlantıyı izlerseniz, sayfanın solundaki satın alma seçeneğinin hemen üstünde hem x86 hem de x64 sürümleri için bir deneme var.
Bradley A. Tetreault

10

Perfmon sayaçlarının tanımı başlangıçtan beri kırılmıştır ve bir nedenden dolayı düzeltilmesi çok zor gibi görünmektedir.

MSDN'deki " Bellek Yönetiminin Gizemleri Açığa Çıktı " videosunda Windows bellek yönetimine iyi bir genel bakış bulunmaktadır : Bellek sızıntılarını izlemek için gerekenden daha fazla konuyu kapsar (örneğin, çalışma kümesi yönetimi) ancak ilgili konularda yeterli ayrıntı verir.


Size perfmon sayacı açıklamaları ile ilgili bir ipucu vermek için , MSDN'de " Özel Bayt Performans Sayacı - Dikkat! "

S: Özel Bayt ne zaman Özel Bayt değildir?

C: Yerleşik olmadığı zaman.

Özel Bayt sayacı işlemin taahhüt ücretini bildirir. Bir başka deyişle, takas durumunda özel belleğin içeriğini tutmak için takas dosyasında ayrılan alan miktarı. Not: Ayrılmamış durumdaki sanal bellekle olası karışıklık nedeniyle "ayrılmış" sözcüğünden kaçınıyorum.


MSDN'deki " Performans Planlama " dan:

3.3 Özel Bayt

3.3.1 Açıklama

Özel bellek, diğer işlemler tarafından paylaşılamayan bir işlem için ayrılan bellek olarak tanımlanır. Bir makinede bu tür birden çok işlem yürütüldüğünde, bu bellek paylaşılan bellekten daha pahalıdır. (Geleneksel) yönetilmeyen dll özel bellek genellikle C ++ statik oluşur ve dll toplam çalışma kümesinin% 5 mertebesindedir.


1
nasıl kırıldığına dair delicesine iyi örnekler nedeniyle oy verin!
Bruno Brant

İlk teklif yanlıştır. "Özel bayt" ı ayırmak, "takas dosyasında (gerçekten pagefile olarak adlandırılır) bir şey tahsis edilmesini gerektirmez. "Özel bayt" ın atanması için bir sayfa dosyanız bile gerekmez. Aslında, özel baytların tahsisi hemen hiçbir yerde herhangi bir alan kullanmaz ve tahsis edildiği kadar kullanamaz.
Jamie Hanrahan

İkinci teklif daha iyi değil. DLL kodunda kullanılan özel baytların genellikle DLL içinde statik olarak ayrılması gerekmez. DLL kodu VirtualAlloc, HeapAlloc (CRTL'de malloc ve yeni), vb. Aramak için mükemmel bir şekilde ücretsizdir. Birincisi sanal boyuttadır (ve aynı girişe sahip kodun her kullanımı için aynıdır), ikincisi fizikseldir (bellek açısından ne kadar zengin veya - açlıktan ölüyor).
Jamie Hanrahan

5

Burada ilginç bir tartışma var: http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/307d658a-f677-40f2-bdef-e6352b0bfe9e/ Bu konuya benim anlayış azat küçük tahsisleri olmasıdır Özel Baytlara veya Çalışma Kümesine yansıtılmaz.

Uzun lafın kısası:

ararsam

p=malloc(1000);
free(p);

Özel Baytlar sadece tahsisi yansıtır, dağıtımı yansıtmaz.

ararsam

p=malloc(>512k);
free(p);

Özel Baytlar tahsisi ve dağıtmayı doğru şekilde yansıtır.


7
Bu, C standart kitaplık bellek işlevlerinin, düşük düzeyli işlem düzeyi bellek yönetiminin üstünde bir bellek yönetim mekanizması olan özel veya Win32 Yığını kullanmasıyla açıklanmaktadır.
Kyberias

@Kyberias, Peki bunun altına nasıl ulaşabiliriz ?
Pacerier

(1) serbest (malloc (1000)); // Bu Özel Baytların sonsuza dek artmasına neden olur mu?
franckspike

2
@franckspike: hayır, belirli bir noktaya yükselir (genellikle yaklaşık 4 kB, ancak bu değişebilir) ve sonra durur, çünkü CRT, OS'den yeni sayfalar istemek yerine önceden serbest bırakılmış belleği yeniden kullanır.
Miral

@Pacerier: VirtualAlloc ve VirtualFree'yi arayabilirsiniz.
Jamie Hanrahan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.