Может ли виртуальная машина Mono использоваться совместно в разных процессах? - PullRequest
0 голосов
/ 02 ноября 2018

Если я захочу запустить два или более консольных приложения под Linux в моно, буду ли я нести накладные расходы на виртуальную машину Mono для каждого процесса, или части виртуальной машины будут повторно использоваться в разных процессах? Если это не так, есть ли способ поделиться частями памяти, используемой моно-виртуальными машинами?

Я хотел бы добиться следующего: предположим, что для виртуальной машины mono требуется 100 МБ, когда многие сборки стандартной библиотеки загружаются приложением. Специфика приложения А заставляет его использовать дополнительные 50 МБ ОЗУ (таким образом, общий объем оперативной памяти, используемой процессом А, составляет 150 МБ), а особенности приложения Б делают его дополнительными 120 МБ ОЗУ (поэтому общий объем оперативной памяти, используемый процессом Б, составляет 220 МБ. ).

Если работает Mono, будут созданы две независимые виртуальные машины Mono, тогда я буду использовать 370 МБ ОЗУ. Однако, если память таких вещей, как базовая библиотека, распределяется между виртуальными машинами, то я бы использовал только 100 + 50 + 120 = 270 МБ ОЗУ.

Дело в том, что я могу быть в ситуации, когда я запускаю десятки или сотни сравнительно небольших приложений, и я обеспокоен тем, что память, зарезервированная каждой моно-виртуальной машиной, значительно ухудшит объем занимаемой памяти при развертывании, в то время как ОЗУ требования каждого отдельного приложения на самом деле не будут такими большими. Я говорю о консольных приложениях (веб-сервисах).

Спасибо

1 Ответ

0 голосов
/ 02 ноября 2018

Как всегда, зависит . ; -)

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

  2. Но есть одна вещь, которую нужно знать. Поскольку Mono является компилятором Just in Time, он переведет язык IL в собственный код вашей платформы. Здесь начинается ваша проблема. Переведенный код генерируется во время выполнения и находится в сегментах памяти, не предназначенных только для чтения. Ядро больше не знает об этой избыточности, поэтому память, занятая для библиотек моно классов, не будет распределена между виртуальными машинами Mono, работающими на тот же хозяин.
    (На самом деле страницы памяти все равно не будут точно совпадать, потому что разные виртуальные машины могут запускать пути кода немного по-разному, например, загружать классы среды выполнения в другом порядке или что-то в этом роде.)

  3. Все было бы легко, если бы это был конец истории, но это не так. Есть еще одна функция моно: AOT (Aigh of Time Compilation) .
    В этом случае оду не компилируется в машинный язык JIT во время выполнения. Вместо этого был предварительно скомпилирован. В этом случае предварительно скомпилированный код только для чтения с точки зрения экземпляров виртуальных машин. Теперь ядро ​​снова поделится предварительно скомпилированным кодом как постоянные данные.
    См. AOT: увеличение общего объема памяти

  4. Но это еще не конец истории. Компилятор AOT поддерживает все функции Mono, он имеет ограничения . Он не может обрабатывать все шаблоны программ. Так что некоторые классы времени выполнения не являются общими. Детали зависят от версии Mono, а также от вашей платформы.
    Для получения более подробной информации см. Ahead of Time Compilation (AOT) .

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

На практике это будет что-то среднее между вашим пессимистическим предположением и вашим оптимистическим предположением. Вы можете быть совершенно уверены, что некоторые сегменты данных виртуальной машины не могут быть общими, даже если AOT действительно хорошо работает. Например. внутренние переменные и экземпляры классов, такие как классы отражения, будут не общими.
AOT охватывает только код IL, но не выражения и объекты, которые зависят только от констант времени разработки, как C ++ constexpr.

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


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

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