Личная память пустого процесса 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 или переключить его на неинтерпретируемый язык, чтобы уменьшить издержки процесса.

Другие вопросы по тегам