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


概要
====

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

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

重要なのは、たとえユーザがいつもヒープ内のメモリブロックを指すようなオ
ブジェクトポインタを操作しているとしても、Python 用ヒープの管理はイン
タプリタ自体が行うもので、ユーザがそれを制御する余地はないと理解するこ
とです。Python オブジェクトや内部使用されるバッファを入れるためのヒー
プ空間のメモリ確保は、必要に応じて、Python メモリマネージャがこのドキ
ュメント内で列挙しているPython/C API 関数群を介して行います。

メモリ管理の崩壊を避けるため、拡張モジュールの作者は決して 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 メモリマ
ネージャに委譲すれば、インタプリタはより正確なメモリフットプリントの全
体像を把握できます。その結果、特定の状況では、Python メモリマネージャ
がガベージコレクションやメモリのコンパクト化、その他何らかの予防措置と
いった、適切な動作をトリガできることがあります。上の例で示したように C
ライブラリのメモリ操作関数を使うと、I/O バッファ用に確保したメモリは
Python メモリマネージャの管理から完全に外れることに注意してください。


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

The following function sets, modeled after the ANSI C standard, but
specifying behavior when requesting zero bytes, are available for
allocating and releasing memory from the Python heap:

void* PyMem_Malloc(size_t n)

   Allocates *n* bytes and returns a pointer of type "void*" to the
   allocated memory, or *NULL* if the request fails. Requesting zero
   bytes returns a distinct non-*NULL* pointer if possible, as if
   "PyMem_Malloc(1)" had been called instead. The memory will not have
   been initialized in any way.

void* PyMem_Realloc(void *p, size_t n)

   Resizes the memory block pointed to by *p* to *n* bytes. The
   contents will be unchanged to the minimum of the old and the new
   sizes. If *p* is *NULL*, the call is equivalent to
   "PyMem_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 "PyMem_Malloc()" or "PyMem_Realloc()". If the
   request fails, "PyMem_Realloc()" returns *NULL* and *p* remains a
   valid pointer to the previous memory area.

void PyMem_Free(void *p)

   Frees the memory block pointed to by *p*, which must have been
   returned by a previous call to "PyMem_Malloc()" or
   "PyMem_Realloc()".  Otherwise, or if "PyMem_Free(p)" has been
   called before, undefined behavior occurs. If *p* is *NULL*, no
   operation is performed.

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

TYPE* PyMem_New(TYPE, size_t n)

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

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

   Same as "PyMem_Realloc()", but the memory block is resized to "(n *
   sizeof(TYPE))" bytes.  Returns a pointer cast to "TYPE*". On
   return, *p* will be a pointer to the new memory area, or *NULL* in
   the event of failure.  This is a C preprocessor macro; p is always
   reassigned.  Save the original value of p to avoid losing memory
   when handling errors.

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 による新しいオブジェクト型の定義や実
装に関する記述の中で説明します。
