Erlangプロセスの作成¶Erlangのプロセスは、オペレーティングシステムのスレッドやプロセスと比べて軽量です。Erlangのプロセスを新規の生成する場合には、HiPEサポートなしで、SMPエミュレータがない環境では、309ワード(32ビット環境では1ワード4バイト)のメモリを消費します。SMPサポートおよび、HiPEサポートを使用すると、それぞれサイズが大きくなります)。erlang:system_info(wordsize).309このプロセスのサイズには233ワードのヒープ領域(スタックも含みます)が含まれます。ガーベジコレクタは必要に応じてヒープの領域を増加させます。末尾再帰にしなければなりません。末尾再帰にしなかった場合には、ループごとにスタックを消費して、プロセスが異常終了することになります。[]).io:format/2の呼び出しは行われません。代わりにリターンアドレスがloop/0の一回の呼び出しごとにスタックに積まれていきます。初期ヒープサイズ¶デフォルトの初期ヒープサイズが233ワードしかない理由としては、Erlangのシステムが何十万、何百万というプロセス数をサポートをするために、極めて保守的に設定されているからです。ガーベジコレクタは必要に応じて、ヒープのサイズを拡大したり、縮小したりします。比較的プロセス数が少ないシステムでは、elrの+hオプションを使用するか、CPU1プロセスに対して、プロセス数が1のシステムではspawn_opt/4のmin_heap_sizeオプションを使用して最低ヒープサイズを増やすことで、パフォーマンスが上がる可能性があります。メリットとしては2要素あります。最初に、ガーベジコレクタはヒープサイズを拡大しますが、少しずつ増加させていきます。この場合、少しずつメモリを確保するよりも、大きなサイズのヒープをプロセス生成時に直接確保した方が効率的である、という点です。2番目は、ガーベジコレクタがヒープサイズを縮小する場合になります。これはヒープが必要量よりもはるかに多い量確保されている場合に縮小が行われますが、最小のヒープサイズを設定することで、これを防ぐことができます。Warningエミュレータはおそらくより多くのメモリを消費します。いうのは、ガーベジコレクタが実行される回数が少なく、より大きなバイナリデータが長期間保持されることになるからです。プロセス数が多いシステムの場合には、新しいプロセスのヒープサイズが小さいほど、処理するタスクの生成にかかる時間が少なくなります。プロセスが完了した場合には、計算結果は他のプロセスに送られ、終了します。計算を行うのに必要最低限のプロセスサイズが設定されている場合にはガーベジコレクションはまったく実行されない可能性があります。最適化を行う場合には適切に測定せずに行おうとしてはいけません。プロセスメッセージ¶Erlangプロセス間のメッセージに含まれる全てのデータは、同じErlangノード上のrefcバイナリを覗いて、コピーされます。メッセージが他のErlangノードに送信される場合には、まず最初に、Erlang外部フォーマットと呼ばれるものにエンコードされて、TCP/IPソケットを通じて送信されます。受信側のErlangノードは、まずはメッセージをデコードし、正しいプロセスに分配します。定数Erlang項(リテラルとも呼ばれる)は定数プールというところに保存されます。ロードされたモジュールごとに、それぞれプールが存在します。以下のような関数があったとします。{31,28,31,30,31,30,31,31,30,31,30,31}).この関数を実行しても、ガーベジコレクタが実行された次の回に実行された時を除き、毎回タプルが生成されることはありません。このタプルはモジュールの定数プール内に配置されます。定数が他のプロセスに送信されたり、ETSテーブルに保存される場合にはコピーされることになります。この理由というのは、ランタイムシステムは定数を含むコードを、適切なタイミングでアンロードできるように、すべての定数の参照を追跡できるようになっていなければならないのですが、他のプロセスなどに行ってしまうと、追跡が難しいため、コピーされます。コードがアンロードされると、その定数はプロセスのヒープにコピーされます。定数のコピーは、将来のリリースで削除される可能性があります。共有することによる損失¶sub-termの共有は、termが他のプロセスに送信するときにも保護されません。初期のプロセスの引数として生成の呼び出し時に渡されるか、ETSテーブルの中に格納されます。ほとんどのアプリケーションでは、メッセージの送信時にはsub-termの共有は行いません。は深いリストを作成します。組み込み関数を使用すると、共有が無視されていれば、深いリストのサイズを計算することができます。同じ数値を返すようになります。共有はここで失われたと言うことが分かります。Erlang/OTPの将来のリリースでは、オプションで、共有を保存する機能を実装しようと考えています。共有の保存に関して、デフォルトの振る舞いをどのようにするかはまだ計画がありませんが、これが導入されると、多くのErlangアプリケーションにとっては、ペナルティがあるでしょう。SMPエミュレータ¶R11Bから導入されたSMPエミュレータにより、マルチコアやマルチCPUのコンピュータ上でのErlangがスケジューリングしているスレッドの実行が改善されるでしょう。一般的にはコア数と同数のスレッドでもっとも効果を発揮するでしょう。それぞれのスケジューラスレッドはSMPエミュレータがないErlangのスケジューラと同じようにErlangプロセスをスケジューリングします。SMPエミュレータを使用してパフォーマンスを古城させるには、ほとんどの箇所において、一つ以上のErlangプロセスが走るようなアプリケーション構造にする必要があります。なければ、Erlangエミュレータは同時に一つのErlangプロセスしか実行することができません。それだけではなく、マルチプロセス用のロックのオーバーヘッドのコストも支払う必要があります。ロックのオーバーヘッドをできるだけ減らそうとしても、完全にゼロにはなりません。ベンチマークは並列であっても、シーケンシャルであるかのように見えることがあります。この[estone?]ベンチマークは実際には、完全に直列実行になっています。そのため、リングベンチマークの一般的な実装では、一つのプロセスがアクティブである場合には他のプロセスは文を受け取るまでは待っていることになります。並列性に関する潜在能力がどの程度あるかや、スケールしないボトルネックがどれだけあるかについては、プロファイルを使用することで、そのアプリケーションの感覚を得ることができます。