メモリ管理
**********


概要
====

Python におけるメモリ管理には、全ての Python オブジェクトとデータ構造
が入ったプライベートヒープ (private heap) が必須です。プライベートヒー
プの管理は、内部的には *Python メモリマネージャ (Python memory
manager)* が確実に行います。Python メモリマネージャには、共有
(sharing)、セグメント分割 (segmentation)、事前割り当て (preallocation)
、キャッシュ化 (caching) といった、様々な動的記憶管理の側面を扱うため
に、個別のコンポーネントがあります。

最低水準層では、素のメモリ操作関数 (raw memory allocator) がオペレーテ
ィングシステムのメモリ管理機構とやりとりして、プライベートヒープ内に
Python 関連の全てのデータを記憶するのに十分な空きがあるかどうか確認し
ます。素のメモリ操作関数の上には、いくつかのオブジェクト固有のメモリ操
作関数があります。これらは同じヒープを操作し、各オブジェクト型固有の事
情に合ったメモリ管理ポリシを実装しています。例えば、整数オブジェクトは
文字列やタプル、辞書とは違ったやり方でヒープ内で管理されます。というの
も、整数には値を記憶する上で特別な要件があり、速度/容量のトレードオフ
が存在するからです。このように、Python メモリマネジャは作業のいくつか
をオブジェクト固有のメモリ操作関数に委譲しますが、これらの関数がプライ
ベートヒープからはみ出してメモリ管理を行わないようにしています。

It is important to understand that the management of the Python heap
is performed by the interpreter itself and that the user has no
control over it, even if they regularly manipulate object pointers to
memory blocks inside that heap.  The allocation of heap space for
Python objects and other internal buffers is performed on demand by
the Python memory manager through the Python/C API functions listed in
this document.

メモリ管理の崩壊を避けるため、拡張モジュールの作者は決して Python  オ
ブジェクトを C ライブラリが公開している関数: "malloc()" 、 "calloc()"
、 "realloc()" および "free()" で操作しようとしてはなりません。こうし
た関数を使うと、C のメモリ操作関数と Python メモリマネージャとの間で関
数呼び出しが交錯します。 C のメモリ操作関数とPython メモリマネージャは
異なるアルゴリズムで実装されていて、異なるヒープを操作するため、呼び出
しの交錯は致命的な結果を招きます。とはいえ、個別の目的のためなら、 C
ライブラリのメモリ操作関数を使って安全にメモリを確保したり解放したりで
きます。例えば、以下がそのような例です:

   PyObject *res;
   char *buf = (char *) malloc(BUFSIZ); /* for I/O */

   if (buf == NULL)
       return PyErr_NoMemory();
   ...Do some I/O operation involving buf...
   res = PyString_FromString(buf);
   free(buf); /* malloc'ed */
   return res;

この例では、I/O バッファに対するメモリ要求は C ライブラリのメモリ操作
関数を使っています。Python メモリマネジャは戻り値として返される文字列
オブジェクトを確保する時にだけ必要です。

とはいえ、ほとんどの状況では、メモリの操作は Python ヒープに固定して行
うよう勧めます。なぜなら、Python ヒープは Python メモリマネジャの管理
下にあるからです。例えば、インタプリタを C で書かれた新たなオブジェク
ト型で拡張する際には、ヒープでのメモリ管理が必要です。Python ヒープを
使った方がよいもう一つの理由として、拡張モジュールが必要としているメモ
リについて Python メモリマネージャに *情報を提供* してほしいということ
があります。たとえ必要なメモリが内部的かつ非常に特化した用途に対して排
他的に用いられるものだとしても、全てのメモリ操作要求を Python メモリマ
ネージャに委譲すれば、インタプリタはより正確なメモリフットプリント
(memory footprint) の全体像を把握できます。その結果、特定の状況では、
Python メモリマネージャがガベージコレクションやメモリのコンパクト化、
その他何らかの予防措置といった、適切な動作をトリガできることがあります
。上の例で示したように C ライブラリのメモリ操作関数を使うと、I/O バッ
ファ用に確保したメモリは Python メモリマネージャの管理から完全に外れる
ことに注意してください。


メモリインタフェース
====================

Python ヒープに対してメモリを確保したり解放したりするために、以下の関
数セットが利用できます。これらの関数は ANSI C 標準に従ってモデル化され
ていますが、0 バイトの領域を要求した際の動作についても定義しています:

void* PyMem_Malloc(size_t n)

   *n* バイトをメモリ確保し、確保されたメモリを指す "void*"  型のポイ
   ンタを返します。確保要求に失敗した場合には *NULL* を 返します。 0
   バイトをリクエストすると、可能ならば独立した非 *NULL* のポインタを
   返します。このポインタは "PyMem_Malloc(1)" を代わりに呼んだときのよ
   うなメモリ領域を指しています。確保されたメモリ領域はいかなる初期化
   も行われていません。

void* PyMem_Realloc(void *p, size_t n)

   *p* が指しているメモリブロックを *n* バイトにサイズ変更します。メモ
   リの内容のうち、新旧のサイズのうち小さい方までの領域は変更されませ
   ん。 *p* が *NULL* ならば、この関数は "PyMem_Malloc(n)" と等価にな
   ります; *p* が *NULL* ではなく *n* がゼロに等しい場合は、メモリブロ
   ックはサイズ変更されますが、解放はされず、非 *NULL* のポインタを返
   します。 *p* の値が *NULL* でないならば、それは以前呼び出した
   "PyMem_Malloc()" や "PyMem_Realloc()" の返した値でなければなりませ
   ん。メモリ要求が失敗した場合は、 "PyMem_Realloc()" は *NULL* を返し
   、 *p* は以前のメモリ領域への正しいポインタのままとなります。

void PyMem_Free(void *p)

   *p* が指すメモリブロックを解放します。 *p* は以前呼び出した
   "PyMem_Malloc()" や "PyMem_Realloc()" の返した値でなければなりませ
   ん。それ以外の場合や、 "PyMem_Free(p)" を 呼び出した後だった場合、
   未定義の動作になります。 *p* が *NULL* なら、何も行いません。

以下に挙げる型対象のマクロは利便性のために提供されているものです。
*TYPE* は任意の C の型を表します。

TYPE* PyMem_New(TYPE, size_t n)

   "PyMem_Malloc()" と同じですが、 "(n * sizeof(TYPE))" バイトのメモリ
   を確保します。 "TYPE*" に型キャストされたポインタを返します。メモリ
   には何の初期化も行われていません。

TYPE* PyMem_Resize(void *p, TYPE, size_t n)

   "PyMem_Realloc()" と同じですが、 "(n * sizeof(TYPE))" バイトにサイ
   ズ変更されたメモリを確保します。 "TYPE*" に型キャストされたポインタ
   を返します。関数が終わったとき、 *p* は新しいメモリ領域のポインタか
   、失敗した場合は *NULL* になります。これは C プリプロセッサのマクロ
   で、 p は常に上書きされます。エラーを処理するときにメモリを失う事を
   避けるには、 p の元の値を保存しておいてください。

void PyMem_Del(void *p)

   "PyMem_Free()" と同じです。

上記に加えて、C API 関数を介することなく Python メモリ操作関数を直接呼
び出すための以下のマクロセットが提供されています。ただし、これらのマク
ロは Python バージョン間でのバイナリ互換性を保てず、それゆえに拡張モジ
ュールでは撤廃されているので注意してください。

"PyMem_MALLOC()" 、 "PyMem_REALLOC()" 、 "PyMem_FREE()" 。

"PyMem_NEW()" 、 "PyMem_RESIZE()" 、 "PyMem_DEL()" 。


Object allocators
=================

以下の関数群が利用して Python ヒープに対してメモリを確保したり解放した
り出来ます。これらの関数は ANSI C 標準に従ってモデル化されていますが、
0 バイトを要求した際の動作についても定義しています:

デフォルトではこれらの関数は pymalloc メモリアロケータ を利用します。

警告: これらの関数を呼ぶときには、 *GIL* を保持しておく必要がありま
  す。

void* PyObject_Malloc(size_t n)

   *n* バイトを割り当て、そのメモリを指す "void*" 型のポインタを返しま
   す。要求が失敗した場合 *NULL* を返します。

   Requesting zero bytes returns a distinct non-*NULL* pointer if
   possible, as if "PyObject_Malloc(1)" had been called instead. The
   memory will not have been initialized in any way.

void* PyObject_Realloc(void *p, size_t n)

   *p* が指すメモリブロックを *n* バイトにリサイズします。古いサイズと
   新しいサイズの小さい方までの内容は変更されません。

   If *p* is *NULL*, the call is equivalent to "PyObject_Malloc(n)";
   else if *n* is equal to zero, the memory block is resized but is
   not freed, and the returned pointer is non-*NULL*.

   Unless *p* is *NULL*, it must have been returned by a previous call
   to "PyObject_Malloc()", "PyObject_Realloc()" or
   "PyObject_Calloc()".

   If the request fails, "PyObject_Realloc()" returns *NULL* and *p*
   remains a valid pointer to the previous memory area.

void PyObject_Free(void *p)

   Frees the memory block pointed to by *p*, which must have been
   returned by a previous call to "PyObject_Malloc()",
   "PyObject_Realloc()" or "PyObject_Calloc()".  Otherwise, or if
   "PyObject_Free(p)" has been called before, undefined behavior
   occurs.

   *p* が *NULL* の場合何もしません。

In addition, the following macro sets are provided:

* "PyObject_MALLOC()": alias to "PyObject_Malloc()"

* "PyObject_REALLOC()": alias to "PyObject_Realloc()"

* "PyObject_FREE()": alias to "PyObject_Free()"

* "PyObject_Del()": alias to "PyObject_Free()"

* "PyObject_DEL()": alias to "PyObject_FREE()" (so finally an alias
  to "PyObject_Free()")


pymalloc アロケータ
===================

Python has a *pymalloc* allocator optimized for small objects (smaller
or equal to 512 bytes) with a short lifetime. It uses memory mappings
called "arenas" with a fixed size of 256 KiB. It falls back to
"malloc()" and "realloc()" for allocations larger than 512 bytes.

*pymalloc* is the default allocator of "PyObject_Malloc()".

アリーナアロケータは、次の関数を使います:

* 利用できる場合、"mmap()" と "munmap()"、

* それ以外の場合は "malloc()" と "free()"。

バージョン 2.7.7 で変更: The threshold changed from 256 to 512 bytes.
The arena allocator now uses "mmap()" if available.


例
==

最初に述べた関数セットを使って、 概要 節の例を Python ヒープに I/O バ
ッファをメモリ確保するように書き換えたものを以下に示します:

   PyObject *res;
   char *buf = (char *) PyMem_Malloc(BUFSIZ); /* for I/O */

   if (buf == NULL)
       return PyErr_NoMemory();
   /* ...Do some I/O operation involving buf... */
   res = PyString_FromString(buf);
   PyMem_Free(buf); /* allocated with PyMem_Malloc */
   return res;

同じコードを型対象の関数セットで書いたものを以下に示します:

   PyObject *res;
   char *buf = PyMem_New(char, BUFSIZ); /* for I/O */

   if (buf == NULL)
       return PyErr_NoMemory();
   /* ...Do some I/O operation involving buf... */
   res = PyString_FromString(buf);
   PyMem_Del(buf); /* allocated with PyMem_New */
   return res;

上の二つの例では、バッファを常に同じ関数セットに属する関数で操作してい
ることに注意してください。実際、あるメモリブロックに対する操作は、異な
るメモリ操作機構を混用する危険を減らすために、同じメモリ API ファミリ
を使って行うことが必要です。以下のコードには二つのエラーがあり、そのう
ちの一つには異なるヒープを操作する別のメモリ操作関数を混用しているので
*致命的 (Fatal)* とラベルづけをしています。

   char *buf1 = PyMem_New(char, BUFSIZ);
   char *buf2 = (char *) malloc(BUFSIZ);
   char *buf3 = (char *) PyMem_Malloc(BUFSIZ);
   ...
   PyMem_Del(buf3);  /* Wrong -- should be PyMem_Free() */
   free(buf2);       /* Right -- allocated via malloc() */
   free(buf1);       /* Fatal -- should be PyMem_Del()  */

素のメモリブロックを Python ヒープ上で操作する関数に加え、
"PyObject_New()" 、 "PyObject_NewVar()" 、および "PyObject_Del()" を使
うと、 Python におけるオブジェクトをメモリ確保したり解放したりできます
。

これらの関数については、次章の C による新しいオブジェクト型の定義や実
装に関する記述の中で説明します。
