Як структура .NET виділяє пам'ять для OutOfMemoryException?


144

У C ++ насправді можна викинути виняток за значенням, не виділяючи пам'ять на купу, тому ця ситуація має сенс. Але в .NET Framework OutOfMemoryExceptionє еталонним типом, тому він виділяється на купі. Яким чином .NET Framework розподіляє пам'ять, OutOfMemoryExceptionколи недостатньо пам'яті для створення нового об'єкта?


6
Відмінне запитання. Можливо, достатньо пам’яті зарезервовано саме для цієї ситуації.
GreatAndPowerfulOz

19
Для того, щоб додати до інших відповідей тут уже, майте на увазі, що OOM означає, що запитуваний вами блок не може бути виділений. Якщо ви попросите 100Mb, а найбільший доступний блок, час виконання може знайти лише 99Mb, він не вдасться. Але для виключення OOM потрібно лише кілька байт пам'яті. Отже, тому що ваш розподіл не вдався, це не означає, що залишилося нульової пам'яті. Але звичайно, ймовірно, що час виконання залишає деяку пам’ять, щоб прикрити себе в цій ситуації
Джейсон Вільямс

4
Твоє припущення про C ++, до речі, неправильне. Залежно від компілятора, винятки цілком можуть бути виділені на купі. У компіляторі MS немає, але в загальному C ++ ABI винятки виділяються на купі, за винятком того, що є невеликий попередньо виділений аварійний буфер, який буде використовуватися замість цього, якщо на купі не залишилося місця.
Себастьян Редл

Відповіді:


163

Він заздалегідь розміщений під час виконання. Якщо ви вивчите купу будь-якого керованого процесу, ви знайдете екземпляр цього винятку.

Ось попередньо визначені винятки програми Hello World:

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
Виконання не повинно грати за тими ж правилами, що і ваш код. Інший приклад - якщо ви кидаєте, StackOverflowExceptionви можете його зловити, але якщо час виконання викидає цей виняток, ви не зможете його зловити (за замовчуванням).
Брайан Расмуссен

8
Значна частина основних механізмів CLR фактично написана на "C" та "C ++". Отже, цілком можливо, що об'єкт "new'd in place" або пам'яттю іншим чином маніпулюється.
GreatAndPowerfulOz

2
@hvd Що є побічним ефектом? Чи надає OOM сліду стека? Я хотів би, хоча решта інформації є досить статичною?
Джеймс Баррас

7
Що робити, якщо потрібні два винятки тих, хто одного типу, тому що дві нитки кидають їх одночасно?
Traubenfuchs

42

Якщо в процесі виконання виникає стан поза пам'яті, воно викликає ThrowOutOfMemory . Це викликає виняток :: GetOOMException , який конструює об’єкт на стеку і потім копіює його в статично виділений глобальний екземпляр, який потім викидається.

Це не вдалося Exception, хоча, це виняток C ++ оголошено в ex.h . Винятки C ++ перетворюються на керовані винятки в clrex.cpp , який містить код для конкретного викидання попередньо виділеного керованого OutOfMemoryException, який був спочатку виділений та побудований у appdomain.cpp .

Примітка. Деякі з цих вихідних файлів є великими і можуть повісити ваш браузер на кілька секунд, поки він завантажує підсвічування синтаксису.

Сайти для викликів, які Тім Шмелтер пов'язував у коментарі до іншої відповіді, не пов’язані з тим, що час роботи не вичерпано та не може побудувати об'єкт.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.