Прежде чем начать с настоящего вопроса, позвольте мне просто сказать, что я мог бы получить некоторые детали здесь неправильно. Если это так, пожалуйста, арестуйте меня на этих, а также, или даже вместо того, чтобы ответить на мой вопрос.
Мой вопрос касается DLL и .NET, в основном. У нас есть приложение, которое использует довольно немного памяти, и мы пытаемся выяснить, как правильно это измерить, особенно когда проблема возникает главным образом на компьютерах клиентов.
Одна вещь, которая поразила меня, состоит в том, что у нас есть довольно большие сборки .NET с сгенерированным ORM-кодом.
Если бы я использовал неуправляемую (Win32) DLL, имеющую уникальный базовый адрес, несколько одновременных процессов на одном компьютере загружали бы DLL один раз в физическую память и просто отображали ее в виртуальную память для всех приложений. Таким образом, физическая память будет использоваться один раз для этой DLL.
Вопрос в том, что происходит с сборкой .NET. Эта DLL содержит IL, и хотя эта часть может быть разделена между приложениями, а что касается JIT-кода, который является результатом этого IL? Разделяется ли это? Если нет, то как мне измерить, чтобы понять это, на самом деле способствуют проблеме или нет? (Да, я знаю, это будет способствовать, но я не собираюсь тратить много времени на это, пока это не самая большая проблема).
Кроме того, я знаю, что мы не рассматривали базовый адрес для всех сборников .NET в нашем решении, необходимо ли это сделать для сборщиков .NET? И если да, существуют ли некоторые рекомендации по определению этих адресов?
Любое понимание этой области было бы очень желанным, даже если окажется, что это не большая проблема или даже не проблема вообще.
Изменить: просто нашел этот вопрос: сборки .NET и перезагрузка DLL, которые частично отвечают на мой вопрос, но я все равно хотел бы знать, как JIT-код ко всем факторам.
Из этого вопроса и его принятого ответа вытекает, что JIT-код помещается в кучу, а это означает, что каждый процесс загружает общий образ двоичной сборки и создает частную JIT-версию кода внутри своего собственного пространства памяти.
Можно ли измерить это? Если это приведет к получению большого количества кода, нам придется посмотреть на сгенерированный код, чтобы выяснить, нужно ли его настраивать.
Изменить. Здесь добавлен более короткий список вопросов:
- Есть ли смысл в том, что базовые адреса сборников .NET уникальны и не перекрываются, чтобы избежать перезагрузки dll, которые в основном будут использоваться, чтобы просто получить код IL из JITting?
- Как измерить, сколько памяти используется для кода JIT, чтобы выяснить, действительно ли это проблема или нет?
Ответ @Brian Rasmussen здесь указывает, что JITting будет производить копии для каждого процесса JIT-кода, как я и ожидал, но что перезагрузка сборок фактически будет иметь эффект в отношении сокращения использования памяти. Мне придется вникнуть в инструменты WinDbg + SoS, о которых он упоминает, кое-что, что у меня было в моем списке, но теперь я подозреваю, что больше не могу его откладывать:)
Изменить. Некоторые ссылки, которые я нашел по этому вопросу: