2015-08-10 30 views
9

x64 makinede 'server gc mode' ile çalışan bir 'service' hizmetini (owin/webapi + odp.net yönetilen) kullanıyorum. Test paketi belleği çalıştırıldıktan sonra 2Gb civarındaydı. Bu makinede hafıza basıncı ürettim (mevcut tüm belleği ve daha fazlasını tüketen başka bir program). Pencerelerin biraz hafızaya atmak için zorlanacağını tahmin ediyordum. Ancak yoktu. İşte windbg gelen bir çıkıştır:. Net bellek geri alınmıyor

0:018> !dumpheap -stat 
Statistics: 
       MT Count TotalSize Class Name 
00007ffd10445b90  1   24 System.Collections.Generic.GenericEqualityComparer`1[[System.UInt64, mscorlib]] 
... 
00007ffd0f904918 100864  11616976 System.Object[] 
0000005b19face20  84 1810674044  Free 
Total 720544 objects 
Fragmented blocks larger than 0.5 MB: 
      Addr  Size  Followed by 
0000005b1c3c8800 425.6MB 0000005b36d56c50 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]] 
0000005c1c3fcf00 28.2MB 0000005c1e02be58 System.Reflection.Emit.MethodBuilder 
0000005c1e02e5b0 268.0MB 0000005c2ec313d8 System.Threading.OverlappedData 
0000005c2ec31678 142.3MB 0000005c37a830a0 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]] 
0000005d1c541aa0 404.8MB 0000005d35a1a958 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]] 
0000005d35a1e5a8 3.8MB 0000005d35df0c40 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]] 
0000005e1cfe7128 444.1MB 0000005e38c0c3f0 System.Byte[] 
0000005e38c8cfb8 4.5MB 0000005e39110988 System.Byte[] 
0000005e39111bf8 1.2MB 0000005e3923a570 System.Byte[] 
0000005e3923b7e0 0.7MB 0000005e392ed7d0 System.Byte[] 
0000005e392eea40 1.1MB 0000005e39401910 System.Byte[] 

0:018> !heapstat 
Heap    Gen0   Gen1   Gen2   LOH 
Heap0  455256040   24   24  3713672 
Heap1  464550872   24  4327776  727456 
Heap2  428541352  10344768  12616   24 
Heap3  474250128   24  21350456   24 
Total  1822598392  10344840  25690872  4441176 

Free space:             Percentage 
Heap0  446429064   0   0  1819552SOH: 98% LOH: 48% 
Heap1  459823968   0   144   152SOH: 98% LOH: 0% 
Heap2  428520936  34904   24   24SOH: 97% LOH:100% 
Heap3  474044952   0   336   24SOH: 95% LOH:100% 
Total  1808818920  34904   504  1819752 

Yani 48MB etrafında sadece gerçekten kullanılan orada ve 1.8GB boş, belleğin en LOH ama Gen 0 yığın değil, ama .net tekrar o bellek vermedi. Ve bu arada sistem hafıza için açlıktan ölüyordu. Örneğin, IIS yeterli bellek olmadığından başlatılamadı.

Bellek neden pencereler tarafından geri alınmadı?

+0

Bir sunucu benzer MaxLimit set & Süreci, almaya çalışın? –

+0

16, ancak başka hizmetler var. Tüm hafızayı kullanan başka bir araç çalıştırarak yüksek bellek basıncını simüle ettiğimi yazdım. – koruyucu

+0

Lütfen önce soruyu okuyun. SQL değil, IIS değil. Eğer merak ederseniz, Oracle başka bir şehirde bulunan veri merkezinde bir linux sunucusunda çalışıyor. Birden fazla hizmeti çalıştıran bir sunucum var ve bunlardan biri tüm belleği tüketiyor ve pes etmiyor. Testlerimi daha büyük veri setleri üzerinde çalıştırabilir ve 16 GB'lık bir alanı işgal edebilirim. Sorun sadece 50Mb kullanılan ve .net 2Gb yakalar ve işletim sistemine geri vermez. – koruyucu

cevap

2

Kuyu pencereleri boşta "Net" olamaz. .Net çalışma zamanında uzman değilim, deneyimim, uygulamanızın çoğunu tüketmeye başladığında .net çerçevesinin bellekte tutulacağı olmuştur. Göründüğü gibi yavaşça geri verecektir. Pencerelerden bakıldığında, Net'in ne yapacağını bilemez ama .Net, işletim sisteminden bellek aldığını iddia etti ve böylece (.net) pencereyi geri verene kadar bu belleği başka bir uygulamaya aktaramaz. Üzerinde bellek sızıntısı olduğunu gösteren birkaç tane 400 + mb System.Byte [] parçası vardır. İşletim Sisteminin bakış açısıyla, Çerçeve belleği talep etti ve bu hafızayı, açık bir şekilde pencerelerden (açıkça sizden değil) geri verilen pencereler bu konuda hiçbir şey yapamayana kadar kullanmıştı. Uygulamanızı çok dikkatli bir şekilde izlerim çünkü genel nedeni. Net'in belleği serbest bırakmaması bellek sızıntınız olmasıdır. Visual Studio'daki bellek çözümleme araçlarını kullanarak, "Sabitlenmiş" bellekte mi kalıyorsunuz, yoksa sadece onu tutuyor mu göstermelisiniz. Gerçekten kötü suçlular genellikle statik sınıf değişkenleri/olaylarıdır.

SO link: pencereler objects.You maksimum sınırına ulaşıldığında uygulaması & Max bellek kullanımını tanımlamak için bir yol bulmalıyız aracılığıyla manuel çöp toplayıcısı çağırılır serbest bırakmak için uygulamayı compell edemez .NET Free memory usage (how to prevent overallocation/release memory to the OS)

0

, yana GC.Collect(). Uygulama runnning iken

, bellek sadece 4GB ile this

İlgili konular