Когда происходит операция заполнения нуля для массива в C #? - PullRequest
2 голосов
/ 03 февраля 2012

Рассмотрим это в C #:

int[] a = new int[1024];

Все целые числа будут установлены на 0. Традиционно, это выполняется высоко оптимизированной операцией заполнения нуля (например, memset). Однако, поскольку этот массив выделяется CLR, я могу думать об оптимизации, которая довольно проста; CLR может поддерживать нулевую область памяти, чтобы пропустить заполнение нулями в то время, когда мы запрашиваем нашу память.

Теперь, CLR выполняет такую ​​оптимизацию? (В настоящее время я использую .NET 4.0)

Ответы [ 3 ]

2 голосов
/ 03 февраля 2012

Это работает на гораздо более низком уровне. Windows поддерживает поток ядра с низким приоритетом, единственной задачей которого является обнуление содержимого страниц памяти. Называется "нить нить страницы". Эти страницы хранятся в пуле, готовые для использования любым процессом, который генерирует ошибку страницы для зарезервированных, но не зафиксированных страниц. Любой код в Windows выигрывает от этого, а не только от управляемого кода. Целью является безопасность, а не обнуление содержимого ОЗУ отображенных страниц памяти позволит программе шпионить за памятью другого процесса.

Этого не произойдет с вашим массивом, он слишком мал. Он размещается в куче gen # 0, которая всегда будет отображать страницы. Большие массивы, однако, выделяются в куче больших объектов, большой - 85 000 байтов, 8000 байтов для массива double. Выделение LOH может использовать преимущество предварительной инициализации страниц до нуля. Трудно сказать, действительно ли это так, исходный код для этого нигде не доступен. Я бы сказал, что, вероятно, учитывая количество сохраняемых циклов процессора.

2 голосов
/ 03 февраля 2012

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

1 голос
/ 03 февраля 2012

Вы смотрели на IL, созданный для этого кода?Вызов на newarr, вероятно, генерируется для рассматриваемого вызова.Согласно ECMA-355, newarr создает новый одномерный массив на основе нуля и инициализирует элементы массива равными 0 соответствующего типа.В этом случае, поскольку это массив int, элементы будут инициализированы равными 0 при создании.

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