То, как "кучей" и стековой памятью управляют, реализовало, выделенный?

Аргумент насколько я понимаю не это, выдавание исключения плохо, они являются медленными по сути. Вместо этого это об использовании конструкции броска/выгоды как первый класс способ управлять нормальной прикладной логикой вместо более традиционных условных конструкций.

Часто в нормальной прикладной логике Вы выполняете цикличное выполнение, где то же действие является повторенными тысячами/миллионами времен. В этом случае, с некоторым очень простым профилированием (см. класс Секундомера), Вы видите для себя, что выдача исключения вместо говорит простое, если оператор может оказаться существенно медленнее.

На самом деле я когда-то считал, что команда.NET в Microsoft представила методы TryXXXXX в.NET 2.0 ко многим основным типам FCL конкретно, потому что клиенты жаловались, что производительность их приложений была настолько медленной.

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

Microsoft теперь рекомендует, чтобы методы TryXXX использовались особенно в этой ситуации для предотвращения таких возможных проблем производительности.

я мог быть неправым, но это кажется, что Вы не уверены в правдивости "сравнительных тестов", о которых Вы читали. Простое решение: Испытайте его для себя.

12
задан Community 23 May 2017 в 11:51
поделиться

2 ответа

В основном куча реализуется не компилятором, а библиотекой времени выполнения C. Очевидно, этот код очень зависит от платформы. В Unix или Unix-подобных системах реализация обычно основана на системном вызове sbrk / brk, и для уменьшения количества системных вызовов выделяется больший объем памяти. Затем этой памятью управляет диспетчер памяти кучи. Если требуется больше памяти, выполняется новый вызов sbrk. Текущий конечный адрес кучи может быть получен с помощью sbrk (0), если вы заинтересованы в отладке процедур управления кучей. Большинство менеджеров памяти не возвращают память в ОС во время жизни процесса (библиотека времени выполнения gnu c делает это, если соблюдаются определенные ограничения).

Более подробное описание доступно в http: //gee.cs .oswego.edu / dl / html / malloc.html .

4
ответ дан 2 December 2019 в 22:38
поделиться

Современные операционные системы не предоставляют вам прямой доступ к аппаратной RAM, а вместо этого абстрагируют ее в так называемой виртуальной памяти, которая сопоставляется с RAM по запросу. Каждому процессу обычно предоставляется собственная частная копия полного адресного пространства. Это позволяет ОС перемещать память процесса в ОЗУ во время выполнения или даже выгружать ее на диск. Это происходит прозрачно, т. Е. Процесс не уведомляется о таком перемещении и не нуждается в коде для его обработки. (Некоторые приложения реального времени могут использовать методы предотвращения выгрузки памяти.)

При связывании объектных файлов с исполняемым файлом или динамической библиотекой компоновщик статически выделяет память для инструкций процессора функции / метода и для всех глобальных переменные. Когда ОС загружает исполняемую или динамическую библиотеку, он отображает эту заранее выделенную память в реальную.

При запуске каждый поток получает частную область памяти, называемую стеком. Каждый раз, когда вы вызываете функцию / метод, компилятор вставляет код для автоматического выделения (путем увеличения указателя стека) достаточного объема памяти из стека для хранения всех параметров, локальных переменных и возвращаемого значения (если есть), которое использует функция / метод. Если компилятор определяет, что достаточно оставить некоторые переменные в регистрах процессора, он не выделяет для них память в стеке. Когда функция / метод возвращается, он запускает код, сгенерированный компилятором, чтобы освободить (путем уменьшения указателя стека) эту память. Обратите внимание, что деструкторы любых объектов в стеке будут вызываться, когда блок, который они определены в выходах, может занять много времени до возврата. Также, компилятор может повторно использовать выделенную память по своему усмотрению.

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

В отличие от этого, память в куче выделяется с помощью new / delete , для чего компилятор вставляет код для запроса или освобождения памяти с помощью системной библиотеки.

Обратите внимание, что это упрощенное описание, чтобы дать вам представление о том, как работает распределение памяти.

5
ответ дан 2 December 2019 в 22:38
поделиться
Другие вопросы по тегам:

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