Личная память пустого процесса Python, разветвленного многопроцессорным Python
Я создаю несколько дочерних процессов с помощью многопроцессорной обработки Python, но эти дочерние процессы используют много кучи личной памяти, даже когда они являются пустыми процессами. Эта ситуация ухудшается при работе на RHEL с включенной THP(Transparent Hugepage).
- что находится в куче личной памяти пустого дочернего процесса?
- Под linux COW (копирование при записи), не должен ли дочерний процесс совместно использовать всю память, поскольку он не создает / не изменяет никакие страницы памяти? или дочерний процесс пытается изменить / записать страницы памяти, тогда какие данные он пытается изменить / записать?
- или это связано с подсчетом ссылок на объекты типа Python?
Вот простой пример, чтобы продемонстрировать это:
import os
import multiprocessing
print parent process's heap memory in /proc/<pid>/smaps
def emptyProcess():
print child process's heap memory in /proc/<pid>/smaps
return
multiprocessing.Process(name='p1', target=emptyProcess).start()
Выход:
parent: pid: 20920: rss:8228864, shr:2781184, priv:5447680, swap:0, pss:6154240
child: pid: 20921: rss:6397952, shr:5472256, priv:925696, swap:0, pss:3381248
что находится в личной памяти дочернего процесса (925696B или 664KB в куче)?
Память кучи родительского процесса:
006cc000-00be4000 rw-p 00000000 00:00 0 [куча]
Размер: 5216 кБ
Rss: 4120 кБ
Pss: 4120 кБ
Shared_Dirty: 0 кБ
Private_Dirty: 4120 КБ
Ссылка: 4120 кБ
Аноним: 4120 кБ
AnonHugePages: 0 кБ
KernelPageSize: 4 КБ
Дочерний процесс кучи памяти:
006cc000-00be4000 rw-p 00000000 00:00 0 [куча]
Размер: 5216 кБ
Rss: 4396 кБ
Pss: 2530 кБ
Shared_Dirty: 3732 кБ
Private_Dirty: 664 КБ
Ссылка: 676 кБ
Аноним: 4396 кБ
AnonHugePages: 0 кБ
KernelPageSize: 4 КБ
1 ответ
Одной из основных вещей в каждом процессе является интерпретатор Python / VM. Если бы это была программа на C, вы бы увидели совсем другую картину, но даже с "пустым" процессом Python вы все равно понесете накладные расходы на интерпретатор, если не используете многопоточность. У каждого интерпретатора Python есть куча кучи, стека и кода, а многопроцессорная обработка Python является оберткой (насколько я знаю) вокруг процессов Linux; так что в основном вы имеете дело с fork()
, Создание нового процесса означает, что вы получите новый интерпретатор Python. Хотя операционная система довольно умна в отношении копирования при записи, накладные расходы интерпретаторов Python увеличиваются.
Я бы порекомендовал попробовать потоки Python или переключить его на неинтерпретируемый язык, чтобы уменьшить издержки процесса.