Подтвердить что ты не робот

Распределение стека и кучи

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

Итак, если у нас есть 1 процесс с 5 потоками в нем, могу ли я сказать, что у нас будет 5 стеков и 1 куча?

Если да, то потоки могут обращаться к другим стекам (или это именно то, почему у них есть отдельные стеки, чтобы предотвратить повреждение), и если там всего одна куча, то очевидно, что все они получают доступ к этой куче, следовательно, необходимо блокировать несколько потоков? Я правильно понимаю это?

4b9b3361

Ответ 1

Да, каждый поток имеет свой собственный стек. В этой сложной необходимости в стеке отслеживается, где метод возвращается после его завершения, он сохраняет адрес возврата. Поскольку каждый поток выполняет свой собственный код, ему нужен собственный стек. Локальные переменные и аргументы метода также хранятся там, что делает их (обычно) потокобезопасными.

Количество куч - более сложная деталь. Вы считаете 1 для мусорной кучи. Это не совсем правильно с точки зрения реализации, три кучи поколений плюс Большая куча объектов - это логически разные кучи, добавляя, что до четырех. Эта деталь реализации начинает иметь значение, если вы слишком много выделяете.

Другой, который вы не можете полностью игнорировать в управляемом коде, - это куча, в которой хранятся статические переменные. Он связан с AppDomain, статические переменные живут до тех пор, пока живет AppDomain. Обычно называется "кучей загрузчика" в литературе .NET. На самом деле он состоит из 3 кучек (высокочастотная, низкочастотная и кубическая), записанные коды и данные типа хранятся там, но они попадают в мелочь.

Далее вниз список игнорирования - это кучи, используемые собственным кодом. Два из них легко видны из класса маршала. Там куча процесса по умолчанию, Windows выделяет из него, также делает Marshal.AllocHGlobal(). И там отдельная куча, где COM хранит данные, Marshal.AllocCoTaskMem() выделяет из нее. Наконец, любой собственный код, с которым вы взаимодействуете, будет иметь свою кучу для поддержки времени выполнения. Количество кучи, используемые этим типом кода, ограничено только количеством встроенных DLL, которые загружаются в ваш процесс. Все эти кучи существуют, вы почти никогда не имеете дело с ними напрямую.

Итак, минимум 10 кучей.

Ответ 2

Короче говоря, да.

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

Очень хороший ресурс для потоковой обработки находится здесь: http://www.albahari.com/threading/

Поток аналогичен процессу операционной системы, в котором запускается приложение. Подобно тому, как процессы запускаются параллельно на компьютере, потоки выполняются параллельно в рамках одного процесса. Процессы полностью изолированы друг от друга; потоки имеют ограниченную изоляция. В частности, потоки разделяют (кучу) память с другими потоки, выполняемые в одном приложении. Частично это объясняется тем, почему threading полезен: один поток может извлекать данные в фоновом режиме, для экземпляр, в то время как другой поток может отображать данные по мере их поступления.

Ответ 3

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

Так как все потоки имеют одно и то же виртуальное адресное пространство, они могут напрямую обращаться к друг другу. Это означает, что один поток может передать переменную в свой стек в качестве аргумента функции, работающей в каком-то другом потоке. Но все же стеки потоков являются отдельными в том, что один поток никогда не толкает или не выталкивает значения в какой-то другой стек потока, а только в свое собственное пространство стека. Так как стеки на x86 и x86-64 растут вниз, в нижней части каждой стековой памяти потока есть специальная страница - так называемая страница защиты. Ошибка стека возникает, если защитная страница когда-либо достигается при работе с стеком.

В неуправляемых языках как C и С++ каждую часть памяти процесса можно получить по желанию с помощью указателей. Один поток может полностью испортить содержимое другого потока потоков и, таким образом, разбивать второй поток (и процесс в целом). В С# эти типы вещей не могут произойти за пределами блоков unsafe, так как стеки управляются CLR.

Ответ 4

Это определенная реализация, но расскажем о самых популярных современных ОС, поскольку вы добавляете тег С#.

сколько кучи существует в процессе.

Обычно 1 за процесс.

Итак, если у нас есть 1 процесс с 5 потоками в нем, могу ли я сказать, что у нас будет 5 стеков и 1 куча?

Да. Каждый поток потребляет 1 МБ виртуального адресного пространства сразу для стека потоков.

Если да, то потоки могут обращаться к другим стекам (или это именно то, почему у них есть отдельные стеки, чтобы предотвратить повреждение), и если там всего одна куча, то очевидно, что все они получают доступ к этой куче, следовательно, необходимо блокировать несколько потоков? Я правильно понимаю это?

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