10.1. メモリ
効率的なプログラミングを始めるスタートとして、データ型ごと、あるいは操作によって、どのぐらいのメモリを消費するのか、という知識を身につけるのは、悪くない選択と言えるでしょう。Erlangのデータ型や、その他の要素がどのぐらいメモリを消費するのかというのは実装依存になります。今回はerts-5.2システム(OTPリリースR9B)におけるメモリ消費量の数値をお見せしますが、R13においても、それほど大きな違いはありません。
メモリ消費量の単位はメモリワードというものになります。32ビット実装と64ビット実装の両方がありますが、メモリワードはそれに依存し、それぞれ4バイト、もしくは8バイトになります。
データ型ごとのメモリサイズ
データ型 |
メモリサイズ |
数値(-16#7FFFFFF < i <16#7FFFFFF) |
1ワード |
数値(上記の範囲を超える大きな数値) |
3..Nワード |
アトム |
1ワード。ただし、アトムはアトムテーブルを参照するが、そちら
でもメモリは消費する。アトムのテキストは初めて出てきた
ユニークなものだけがこのテーブルに格納されていく(同じアトム
は2回以上保存されることはない)。このアトムテーブルは
ガベージコレクタでは掃除されることはない。 |
浮動小数点数 |
32ビットアーキテクチャ: 4ワード
64ビットアーキテクチャ: 3ワード |
バイナリ |
3..6 + データ(共有可能) |
リスト |
要素ごとに1ワード + それぞれの要素サイズ |
文字列(数値の入ったリストと同等) |
1文字ごとに2ワード |
タプル |
2ワード + それぞれの要素サイズ |
プロセスID |
現在のローカルノード上のプロセスの識別子: 1ワード。
他のノード上のプロセスの識別子: 5ワード
ただし、プロセス識別子はプロセステーブルを参照します。
プロセステーブルは上記とは別にメモリを消費します。 |
ポート |
現在のローカルノード上のポートの識別子: 1ワード。
他のノード上のポートの識別子: 5ワード
ただし、ポート識別子はポートテーブルを参照します。
ポートテーブルは上記とは別にメモリを消費します。 |
参照 |
- 32ビットアーキテクチャ:
- 現在のローカルノードからの参照: 5ワード。
他のノードからの参照: 7ワード
- 64ビットアーキテクチャ:
- 現在のローカルノードからの参照: 4ワード。
他のノードからの参照: 6ワード
ただし、参照はノードテーブルを参照し、
これもメモリを消費します。
|
fun |
9~13ワード + 環境のサイズ
ただし、funはfunテーブルを参照し、これもメモリを消費します。 |
ETSテーブル |
768ワード + それぞれの要素で消費される量
(6ワード+要素内のデータサイズ)。テーブルは必要に応じて拡張
される。 |
Erlangプロセス |
327ワード(そのうちヒープは233ワード |
10.2. システムの限界
Erlangは言語仕様では、プロセス数やアトムの長さなどに関して、限界を設けていません。しかし、パフォーマンスや、メモリ消費の節約のために、実際のErlangの実装や、実行環境に関しては、制約が設けられています。
- プロセス
- 同時に起動できるErlangのプロセス数は32768です。この制限は起動時に設定することで最大268435456プロセスまで増やすことができます。erl(1)のドキュメント内の+Pシステムフラグの説明を参照してください。ただし、32ビット環境ではその最大のプロセス数に達する前に、メモリが足りなくなって起動できなくなります。
- 分散ノード数
- 知っているノード数
- リモートノードYは他のノードXのpid, ポート、参照、funなどを通じて、YからXを「知っている」という状態を作ることができます。あるいは、XとYがつながっている場合もそうです。同時に知ることができるノード数の最大値は、ノード名として使用できるアトムの最大数により制限されます。リモートノードに関するすべてのデータは、ノード名のアトムを除いてガベージコレクタで回収されます。
- 接続するノード数
- 同時に接続できるノード数というのは、同時に知ることができるリモートノード数と、Erlangのポートの利用可能な最大数、もしくは利用可能な最大のソケット数により制限されます。
- アトムの文字数
- 255
- アトムの数
- 持てるアトムの限界数は1048576です。
- Etsテーブル数
- デフォルトでは1400ですが、 ERL_MAX_ETS_TABLES という環境変数を設定することで変更することができます。
- タプルの要素数
- タプルの要素数の最大値は67108863(26ビットの整数で表される範囲)です。これとは別の要因になりますが、使用できるメモリの限界によって、そのサイズのタプルを実際に作るのは難しいでしょう。
- バイナリのサイズ
- Erlangの32ビット実装では、ビット文法を使って作成したり、一致しているかどうか見てみるような処理を行える限界は536870911バイトというサイズのデータが最大のサイズになります。また、参考までに64ビット環境であれば2305843009213693951バイトになります。もし限界値を超えてしまった場合には、ビット文法を使ったバイナリの作成は system_limit 例外を出して失敗します。この制限はR11B-4のリリースから適用されることになりましたが、それ以前のリリースでは大きすぎるバイナリに対する操作を行うと、計算に失敗したり、間違った結果を返したりしていました。Erlang/OTPの将来のリリースでは list_to_binary/1 などの、他のバイナリ作成方法についても、同様の制限が加えられる予定です。
- 1つのErlangのノードが割り当てることができるデータの総量
- Erlangランタイムは32(もしくは64)ビットのアドレス空間をフルに使用することができますが、通常の場合、オペレーティングシステムの制限で、ひとつのプロセスが使用できる量はそれよりも少なくなります。
- ノード名の長さ
- Erlangのノード名は、host@shortname, もしくは、host@longnameという形式を持ちます。ノード名はシステム内ではアトムとして扱われるため、ノード名に関してもアトム同様に、最大255文字という制限が課せられます。
- オープンするポート数
- 同時にオープンできるErlangのポート数は、デフォルトでは1024になっています。この制限は起動時に設定することで268435456まで増やすことができます。erlang(3)の ERL_MAX_PORTS の説明を見てください。ただし、32ビット環境ではその最大のポート数に達する前に、メモリが足りなくなってオープンできなくなります。
- オープンするファイル数およびソケット数
- 同時にオープンできるファイルとソケットの最大数は、利用可能なErlangのポート数と、オペレーティングシステムで設定されている限界数に依存します。
- 関数およびfunの引数の数
- 256
Copyright (c) 1991-2009 Ericsson AB