Могу ли я (и хочу ли я когда-нибудь) установить максимальный размер кучи в .net? - PullRequest
26 голосов
/ 19 ноября 2008

Исходя из Java-фона, я привык говорить JVM, каким должен быть максимальный размер кучи. Если работающая программа пытается проглотить больше, чем разрешено, и сборщик мусора не может освободить больше ресурсов, тогда OutOfMemoryError выбрасывается, и все идет на ура. Поэтому настройка максимального размера кучи важна в Java.

Применимо ли это к .net? Можно ли установить пределы размера кучи? CLR продолжает наращивать кучу, пока не достигнет физических ограничений машины? Или это не проблема в .net по какой-то тонкой причине, из-за которой мои Java-мигалки мешают мне видеть?

Ответы [ 4 ]

22 голосов
/ 19 ноября 2008

Вы не можете установить максимальный размер кучи в .Net, если не будете сами размещать CLR в процессе.

Edit: Для управления распределением памяти CLR, включая максимальный размер кучи, вам нужно использовать API хоста для размещения clr и, в частности, использовать «Интерфейсы диспетчера памяти», некоторую стартовую информацию можно найти здесь MSDN Magazine, столбец CLR Inside Out: API хостинга CLR

Редактировать: чтобы ответить на ваш вопрос, зачем вам управлять распределением памяти или, в частности, максимальным размером кучи, обычно вы этого не хотите, но , если , вы пишете приложение, подобное SQL Server или IIS или какое-либо приложение реального времени, тогда у вас будет достаточно веской причины контролировать память и, в частности, избегать подкачки страниц, в противном случае сам CLR и ОС уже довольно хорошо справятся с задачей, и остается чтобы ваше приложение использовало минимальные ресурсы, чтобы все работало хорошо.

14 голосов
/ 19 ноября 2008

Нет, это не относится к .NET. Куча действительно продолжает расти, пока не может больше расти. (Очевидно, это «после попытки восстановить память через GC, увеличьте кучу».) По сути, в .NET GC не так много настроек, как в Java. Вы можете выбрать серверный GC или клиентский, и я думаю, что есть возможность включить / выключить параллельный GC (я найду ссылки через минуту), но это в основном все.

РЕДАКТИРОВАТЬ: Кажется, есть немного больше, хотя и не так много. Запись в блоге Рика Минериха о настройках GC и последующая , похоже, знает больше, чем я, по этому вопросу. Они, вероятно, являются хорошей отправной точкой для дальнейших исследований, но в основном это флаги, а не ограничения памяти, доступные в JVM.

РЕДАКТИРОВАТЬ: Ответ Pop поднимает хороший вопрос - я предполагал, что «нормальная» модель хостинга CLR (т.е. не под вашим контролем). Если вы хотите приложить все усилия, чтобы организовать его самостоятельно, вы, вероятно, получите гораздо больший контроль - за счет дополнительной работы по его размещению. Я не могу сказать, что когда-либо смотрел на эту сторону вещей.

7 голосов
/ 18 марта 2009

Возможно, вы захотите взглянуть на System.Runtime.MemoryFailPoint .

5 голосов
/ 05 августа 2009

Насколько я нашел, не существует простого способа управления размером кучи приложения .Net с помощью CLR.

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

В (обычно Java) серверных средах вы не хотите, чтобы приложение с плохим поведением загружало память за счет других размещенных приложений. Простое решение - ограничить объем памяти, который приложение может использовать для своей кучи. Это достигается с помощью аргумента Java -Xmx, так что вы можете гарантировать, что приложение не будет использовать больше, чем запланировано, например. -Xmx256M. Поскольку выделение памяти в куче во время инициализации может замедлить запуск приложений, Java использует аргумент -Xms, чтобы позволить приложениям, которые много создают объекты во время инициализации, начинать с большого блока кучи вместо того, чтобы JVM постоянно изменяла размер кучи по мере идет.

.Net CLR не имеет этой способности. Я подозреваю, что это потому, что .Net CLR не является виртуальной машиной. CLR - это API (я бы добавил, достаточно всеобъемлющий), который служит адаптером для нативных .dll, что приравнивается к подходу, гораздо более похожему на исполняемый файл, когда дело доходит до управления памятью.

Я задал этот вопрос о разработке SharePoint и действительно слышал, что можно было бы управлять размером кучи с помощью модулей IIS, называемых веб-приложениями, с помощью которых вы можете указать IIS ограничить память данного веб-приложения. Интересно, так ли это, потому что IIS имеет настроенные подпрограммы, которые заменяют / переопределяют new () / malloc () / etc и, таким образом, могут предоставлять этот тип управления клиентским приложениям. Это означает, что автономным приложениям .Net не повезло, если вы не хотите написать собственный менеджер памяти на C ++ и создать интерфейс для .Net

.
...