Как обрабатываются переменные формы VB.NET - PullRequest
0 голосов
/ 21 сентября 2019

Класс формы, показанный здесь, имеет метод, который обрабатывает событие нажатия кнопки.Локальный тип значения x объявляется и инициализируется.Я понимаю, что это находится в кадре стека для кода кнопки на время метода.Код кнопки также создает экземпляр класса foo с именем f и вызывает его метод doSomething.Я понимаю, что кадр стека для кнопки теперь содержит ссылку на объект f, который находится в куче.Метод doSomething объекта f объявляет и инициализирует тип локального значения y.Где хранится y?Это в одном стеке?Это в куче, в соответствии с объектом F?или, когда doSomething вызывает doSomethingElse, используется другой стек?Предположительно, тот же механизм используется, когда одна форма создает другую?

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim x As Integer
        x = 5
        Dim f As New foo
        f.doSomething()
    End Sub
End Class

Public Class foo
    Public Sub doSomething()
        Dim y As Integer
        y = 6
        Call doSomethingElse()
    End Sub

    Public Sub doSomethingElse()
        Dim z As Integer
        z = 7
    End Sub
End Class

1 Ответ

0 голосов
/ 25 сентября 2019

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

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

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

Переменным, выделенным в куче, выделяется память во время выполнения, и доступ к этой памяти являетсянемного медленнее, но размер кучи ограничен только размером виртуальной памяти.Элемент кучи не имеет зависимостей друг от друга и всегда может быть доступен случайным образом в любое время.Вы можете выделить блок в любое время и освободить его в любое время.Это значительно усложняет отслеживание того, какие части кучи выделены или свободны в любой момент времени.enter image description here

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

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

ref: http://net -informations.com / faq / net / stack-heap.htm

Подробнее

Какие объекты размещены в стеке и какие объекты размещены в куче?

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

Ссылочные типы (классы, интерфейсы, делегаты) всегда выделяются в куче.

Когда вы передаете ссылочный объект в качестве параметра или присваиваете его переменной, вы фактически передаете его ссылку.Ссылка (не ссылочный объект) может быть размещена как в стеке, так и в куче.

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

Каждый раз, когда объект передается в качестве ссылки, сама ссылка копируется.Это означает, что вы можете изменить ссылку, чтобы она указывала на другой объект, не затрагивая сам предыдущий объект или другие ссылки, указывающие на него.Ссылка является легкой и всегда имеет постоянный размер (32-разрядный или 64-разрядный в зависимости от разрядности ОС), поэтому ее копирование (и, следовательно, передача типов ссылок) считается дешевым.

Типы значений (производные от System.ValueType,например, int, bool, char, enum и любая структура) могут быть размещены в куче или в стеке, в зависимости от того, где они были объявлены.

Если тип значения был объявлен как переменная внутри метода, тогда этохранится в стеке.Если тип значения был объявлен как параметр метода, он сохраняется в стеке.Если тип значения был объявлен как член класса, он сохраняется в куче вместе со своим родителем.Если тип значения был объявлен как член структуры, то он сохраняется везде, где хранится эта структура.Начиная с C # 7.2, структура может быть объявлена ​​как ref struct, и в этом случае она всегда будет размещаться в стеке, предотвращая ее объявление в ссылочных типах.

Экземпляры типов значений передаются копией (если не используются со ссылочной семантикой, см. Ниже).Это означает, что каждый раз, когда тип значения назначается переменной или передается в качестве параметра, значение копируется.

Поскольку копирование типов значений может быть дорогостоящим в зависимости от размера объекта, не рекомендуется объявлять память-heavy объекты как типы значений.

Поскольку каждый тип в C # происходит от System.Object, типы значений могут быть назначены переменным или переданы методам, которые ожидают объект.В таких случаях значение копируется и сохраняется в куче, обернутой как ссылочный тип, в операции, известной как упаковка.

ref: https://dev.to/tyrrrz/interview-question-heap-vs-stack-c-5aae#targetText=In%20C%23%20there%20are%20two,can%20be%20accessed%20from%20anywhere.

...