Действительно ли возможно, что утечка памяти может происходить в стеке в.NET также?

Утечка памяти, когда существует неиспользованная память в приложении, и GC может собрать его, обычно происходит, будут ли некоторые, где в приложении мы сохраняем нежелательную сильную ссылку объекта и GC, способный найти путь (Прямой и косвенный), таким образом, это сможет освободить этот объект, но это все верно о ссылочном типе, которые означают в выделении памяти "кучи".

Но что относительно стека И поскольку далеко я знаю, что GC не будет ответственный для чистки стека, который он автоматически уберет, когда функция возвратится.

Таким образом, мой вопрос, это - там шанс, что утечка памяти будет происходить в стеке также?, если да затем, в какой сценарий и что является лучшими практиками для предотвращения этого вида утечки.

5
задан Firoz 25 February 2010 в 08:18
поделиться

6 ответов

Если вы пишете рекурсивные функции, которые сохраняют локальные в стеке ссылки на большие данные, которые не нужны в субрекурсивных вызовах, то это тип пространства утечка, но на практике это очень необычно.

В общем, если у вас есть что-то вроде

Main() {
    var s = ReadInAGiganticString();   // say 10 Megs long
    Server(s.Substring(0,5));          // but I only care about first 5 chars
}
Server(s) {
    while(true) { ... }                // but 10M is on stack forever
}

, то это своего рода утечка пространства стека, но опять же, на практике это маловероятно. Исправить это просто:

Main() {
    var s = ReadInAGiganticString();
    var t = s.Substring(0,5);
    s = null;                         // the fix
    Server(t);
}
Server(s) {
    while(true) { ... }
}

В общем, если у вас когда-либо была гигантская переменная в стеке прямо перед вызовом, который будет длиться «долгое время», и эта переменная больше не используется, вы можете обнулить ее, чтобы убедиться, что она может быть GC'd перед переходом к «длинному» вызову.

(Возможно, оптимизатор сделает это за вас на основе анализа достижимости.)

Обратите внимание, что приведенный выше ответ относится к ссылкам на объекты, размещенные в куче, которые размещены в стеке. Если, с другой стороны, у вас есть выделенная стеком память (например, гигантская структура или stackalloc), исправить это не так просто, но на практике это еще реже (кто когда-либо создает гигантские структуры?).

2
ответ дан 15 December 2019 в 06:24
поделиться

Утечка памяти может произойти, если вы не сможете правильно освободить неуправляемые ресурсы. Поэтому я боюсь, что если вы отправите управляемый объект в метод, а этот объект обернет неуправляемый ресурс и не удастся правильно освободить неуправляемый ресурс, произойдет утечка памяти. Стек освободит управляемую ссылку, но неуправляемый ресурс останется живым.

1
ответ дан 15 December 2019 в 06:24
поделиться

Переменные, выделенные в стеке, уничтожаются после завершения блока. Таким образом, утечка памяти невозможна. Практика кровати заключается в создании переменной, которая используется только в данном блоке за пределами этого блока

0
ответ дан 15 December 2019 в 06:24
поделиться

Как вы говорите, GC не очищает стек. Однако пространство, используемое стеком, освобождается во время раскрутки. Так как стек выталкивается, указатель стека перемещается «назад», и, таким образом, пространство можно использовать повторно.

При нехватке места в стеке возникает исключение StackOverflowException. Обычно это происходит из-за ошибки программирования с неограниченной рекурсией.

0
ответ дан 15 December 2019 в 06:24
поделиться

Нет, пока вы используете безопасный код, утечки памяти не могут произойти для переменных стека.

0
ответ дан 15 December 2019 в 06:24
поделиться

Не зная слишком много о внутреннем устройстве .NET, я бы сказал, что если у вас есть утечка стека у вас будет сбойная программа, поскольку адрес возврата функции / метода также хранится в стеке (скорее всего, в любом случае).

Если ваш стек каким-то образом не выровнен, у вас будут гораздо более серьезные проблемы, чем утечка памяти.

Обычно параметры метода и возвращаемые значения хранятся в стеке (если они не оптимизированы для отправки через регистры процессора).

0
ответ дан 15 December 2019 в 06:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: