.NET framework OutOfMemoryException için belleği nasıl ayırır?


144

C ++ 'da, bir yığın üzerinde bellek ayırmadan değere göre bir istisna atmak mümkündür, bu nedenle bu durum mantıklıdır. Ancak .NET çerçevesinde OutOfMemoryExceptionbir başvuru türüdür, bu nedenle bir yığın üzerinde ayrılır. OutOfMemoryExceptionYeni bir nesne oluşturmak için yeterli bellek olmadığında .NET framework nasıl bellek ayırır?


6
Mükemmel soru. Belki de bu durum için yeterli hafıza ayrılmıştır.
GreatAndPowerfulOz

19
Sadece burada bulunan diğer cevaplara eklemek için, OOM'nin talep ettiğiniz bloğun tahsis edilemeyeceği anlamına geldiğini unutmayın. 100Mb ve çalışma zamanının bulabileceği en büyük blok için yalnızca 99Mb isterseniz, başarısız olur. Ancak bir OOM istisnasının yalnızca birkaç bayt belleğe ihtiyacı vardır. Bu nedenle, ayırmanız başarısız olduğu için sıfır bellek kaldığı anlamına gelmez. Ama elbette, çalışma zamanının bu durumda kendini örtmek için biraz bellek ayırması muhtemeldir
Jason Williams

4
Bu arada C ++ ile ilgili varsayımlarınız yanlış. Derleyiciye bağlı olarak, öbek üzerinde istisnalar ayrılabilir. MS derleyicisi bunu yapmaz, ancak Ortak C ++ ABI'de, yığın üzerinde boş alan yoksa bunun yerine kullanılacak küçük, önceden yerleştirilmiş acil durum arabelleği dışında istisnalar yığın üzerinde ayrılır.
Sebastian Redl

Yanıtlar:


163

Çalışma zamanı tarafından önceden konumlandırılır. Yönetilen herhangi bir işlemin yığınını keşfederseniz, bu istisnanın bir örneğini bulacaksınız.

İşte Hello World uygulamasının önceden belirlenmiş istisnaları:

0:003> !dumpheap -stat -type Exception
Statistics:
      MT    Count    TotalSize Class Name
735f2920        1           84 System.ExecutionEngineException
735f28dc        1           84 System.StackOverflowException
735f2898        1           84 System.OutOfMemoryException
735f2744        1           84 System.Exception
735f2964        2          168 System.Threading.ThreadAbortException


36
Çalışma zamanının kodunuzla aynı kurallara uyması gerekmez. Başka bir örnek, eğer StackOverflowExceptionattığınızda onu yakalayabilirsiniz, ancak çalışma zamanı bu istisnayı atarsa ​​(varsayılan olarak) yakalayamazsınız.
Brian Rasmussen

8
CLR'nin altında yatan mekanizmaların çoğu aslında "C" ve "C ++" ile yazılmıştır. Bu nedenle, nesnenin "yerinde yeni olması" veya hafızanın başka bir şekilde manipüle edilmesi tamamen mümkündür.
16'da GreatAndPowerfulOz

2
@hvd Yan etkisi nedir? OOM yığın izlemesi veriyor mu? Geri kalan bilgiler oldukça statik olsa olurdu?
James Barrass

7
Aynı iş parçacığı aynı anda iki istisna gerekiyorsa, iki iş parçacığı aynı anda fırlatırsa ne olur?
Traubenfuchs

42

Çalışma zamanında bellek yetersiz durumuyla karşılaşıldığında ThrowOutOfMemory öğesini çağırır . Bu , yığındaki nesneyi oluşturan ve daha sonra atılan statik olarak ayrılmış bir genel örneğe kopyalayan Exception :: GetOOMException öğesini çağırır .

Bu, yönetilen İstisna değildir, ancak ex.h içinde bildirilen bir C ++ istisnasıdır . C ++ İstisnaları , başlangıçta appdomain.cpp'de ayrılmış ve oluşturulmuş önceden yerleştirilmiş yönetilen OutOfMemoryException özel durumunu atmak için kod içeren clrex.cpp içindeki yönetilen İstisnalara dönüştürülür .

Not: Bu kaynak dosyalardan bazıları büyüktür ve sözdizimi vurgulamasını yüklerken tarayıcınızı birkaç saniye asabilir.

Tim Schmelter'in diğer cevaba yaptığı bir yorumda bağladığı çağrı siteleri, çalışma süresinin belleği tükenmesi ve bir nesne oluşturamamasıyla ilgili değildir.

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.