3 つの大きなリストがあります。1 つは bitarray (モジュール bitarray 0.8.0) を含み、残りの 2 つは整数の配列を含みます。
l1=[bitarray 1, bitarray 2, ... ,bitarray n]
l2=[array 1, array 2, ... , array n]
l3=[array 1, array 2, ... , array n]
これらのデータ構造は、かなりの量の RAM (合計 16GB まで) を消費します。
次を使用して12のサブプロセスを開始した場合:
multiprocessing.Process(target=someFunction, args=(l1,l2,l3))
これは、サブプロセスごとに l1、l2、および l3 がコピーされるということですか、それともサブプロセスがこれらのリストを共有するということですか? または、より直接的に言えば、16GB または 192GB の RAM のどちらを使用しますか?
someFunction は、これらのリストからいくつかの値を読み取り、読み取った値に基づいていくつかの計算を実行します。結果は親プロセスに返されます。リスト l1、l2、および l3 は someFunction によって変更されません。
したがって、サブプロセスはこれらの巨大なリストを必要とせず、コピーせず、代わりに親と共有するだけであると想定します。Linuxでのコピーオンライトアプローチにより、プログラムが16GBのRAMを使用することを意味します(開始するサブプロセスの数に関係なく)? 私は正しいですか、それともリストがコピーされる原因となる何かが欠けていますか?
編集:この件についてもう少し読んだ後、私はまだ混乱しています。一方では、Linux はコピー オン ライトを使用します。これは、データがコピーされないことを意味します。一方、オブジェクトにアクセスすると、その参照カウントが変更されます(理由と意味はまだわかりません)。それでも、オブジェクト全体がコピーされますか?
たとえば、someFunction を次のように定義するとします。
def someFunction(list1, list2, list3):
i=random.randint(0,99999)
print list1[i], list2[i], list3[i]
この関数を使用すると、サブプロセスごとに l1、l2、および l3 が完全にコピーされることになりますか?
これを確認する方法はありますか?
EDIT2もう少し読んで、サブプロセスの実行中にシステムの総メモリ使用量を監視した後、サブプロセスごとにオブジェクト全体が実際にコピーされているようです。そして、参照カウントが原因のようです。
私のプログラムでは、l1、l2、および l3 の参照カウントは実際には必要ありません。これは、親プロセスが終了するまで、l1、l2、および l3 がメモリに (変更されずに) 保持されるためです。それまでは、これらのリストで使用されているメモリを解放する必要はありません。実際、プログラムが終了するまで、(これらのリストおよびこれらのリスト内のすべてのオブジェクトに対して) 参照カウントが 0 を超えたままになることは確かです。
さて、問題は、オブジェクトが各サブプロセスにコピーされないようにするにはどうすればよいですか? これらのリストとこれらのリスト内の各オブジェクトの参照カウントを無効にすることはできますか?
EDIT3 追記です。サブプロセスは、これらのリスト内の やオブジェクトl1
をl2
変更する必要はありません。l3
サブプロセスは、サブプロセスごとにメモリがコピーされることなく、これらのオブジェクトの一部を参照できる必要があるだけです。