Проверяя потребление памяти QEMU, я наблюдаю следующий шаблон на моем сервере aarch64 (на хосте и в гостевой системе выполняется centos 7.4, который использует размер страницы 64 КБ на aarch64, в случае необходимости):
| guest mem size | qemu RSS size |
+----------------+---------------+
| 1g | 868m |
| 4g | 2.2g |
| 8g | 2.8g |
| 16g | 2.8g |
Гость запускает только службы по умолчанию, и я выполняю измерение после его загрузки. В моем понимании Linux обычно просто занимает несколько сотен мегабайт в этом состоянии, но приведенные выше данные показывают, что QEMU потребляет гораздо больше памяти, чем это.
Возьмем, к примеру, случай памяти 4g, приведенный ниже вывод свободной команды показывает, что гостевая ОС использует около 367 м памяти (144 м «использовано» плюс 222 м «бафф / кэш»). С другой стороны, QEMU потребляет 2,2 г памяти на хосте (см. Таблицу выше).
# free
total used free shared buff/cache available
Mem: 4097088 147968 3721536 17344 227584 3482176
Swap: 4194240 0 4194240
Я знаю, что QEMU использует память не только для гостевой основной памяти. Например, прошивки отображаются в память. Также для реализации устройств требуется память. Но я не верю, что все другие виды использования могут занимать столько памяти. Поэтому я смотрю на карту памяти процесса QEMU и нахожу блок памяти для гостевой основной памяти (его размер составляет 4194304 байта, что соответствует используемой мной опции CLI "-m 4096"):
# pmap -x $qemu-pid | grep 4194304
0000fffe63e00000 4194304 2179904 2179904 rw--- [ anon ]
Обратите внимание на поле RSS. Это 2179904 тыс. Байт, что составляет около 2,1 г. Это означает, что большая часть памяти, используемой QEMU, действительно используется для гостевой основной памяти.
Гостевая основная память выделяется QEMU с помощью вызова malloc (). Поскольку malloc () просто создает отображение, но не выделяет память, я провожу еще один эксперимент, чтобы определить, когда большая часть гостевой основной памяти выделяется на хосте (или, другими словами, как гость обращается к своей физической памяти на разных этапах при запуске). вверх):
| guest start-up phase | qemu process | guest main memory |
| | RSS size | RSS size (in QEMU) |
|----------------------------------+--------------+--------------------|
| created but not running [1] | 169m | 1m |
| uefi started [2] | 311m | 139m |
| grub started [3] | 807m | 638m |
| kernel started [4] | 2.3g | 2.1g |
| all systemd services started [5] | 2.3g | 2.1g |
[1] I did this by using qemu -S option
[2] I did this by going into uefi shell
[3] This was when grub menu showed up
[4] I did this by going into systemd maintenence mode
[5] This was when the system was ready for user to log in
Это указывает на то, что в то время как микропрограмма осуществляет доступ ко многим частям гостевой физической памяти, но гостевое ядро обращается к гораздо большему. Учитывая, что гостевая ОС в конечном итоге использует только около 367 м памяти, кажется, что ядро Linux затрагивает гораздо больше физической памяти, чем необходимо. У меня вопрос: что конкретно делает ядро, когда оно касается тех частей физической памяти?
Примечание: я решил использовать команду perf mem, чтобы доказать свою догадку. Но это не работает в моей системе aarch64. Кроме того, это не может объяснить, почему.