Erlang
ErlangDay 4

erlang:process_info(Pid, message_queue_len) の話

More than 1 year has passed since last update.

結論

プロセスにメッセージが詰まると破綻するので、 性能検証をする際は message_queue_len を使ってちゃんと確認しましょう。

説明

erlang:process_info/2 は指定したプロセスの情報を取得する仕組みです。その中に message_queue_len という項目があります。

これは何かというと、プロセスのキューに 貯まっている メッセージ数を表示します。

プロセスのキュー?

そもそも Erlang のプロセスに情報を渡す場合はメッセージパッシングが基本です。そのメッセージは受け取った側のプロセスのキューに入ります。

このキューが message_queue です。 message_queue_len はその 現時点でのキューに詰まっているメッセージの長さ です。receive でその送られてきたメッセージにマッチすれば、そのキューから取り出されます。

詰まる?

メッセージをキューから取り出して、メッセージを処理して、次のメッセージをキューから取り出すという処理になります。この メッセージを処理する速度 が送られてくるメッセージが送られてくる速度より遅くなってしまうと、ひたすらキューにメッセージが詰まることになります。

ここが詰まるとそのプロセスはもう使い物にならないと考えて問題ありません。プロセスのキューは 10 万メッセージ以上格納可能です。もちろんその分のメモリーも消費します。

回避策

詰まらないようにする、という悲しい対策しかできません。

おまけ

Erlang/OTP 19.0 で process_flag(message_queue_data, MQD) という機能が入りました。

http://erlang.org/doc/man/erlang.html#process_flag_message_queue_data

これは、キューにメッセージをストアする際に off_heap と on_heap を選べるようになりました。デフォルトは on_heap が有効になっています。

off_heap

プロセスヒープの外部に保存され、プロセスキューに入っているメッセージがガベージコレクションの対象ではななくなります。

on_heap

全てのキューのメッセージが最終的にはヒープにおかれます。ただし、一時的にヒープで無いところに置くことも可能です。

どっちつかえばいいの?

メッセージを多く受け取る可能性がある場合に off_heap を使うといい結果が出る可能性があります。ヒープに置かれたメッセージのためのガベージコレクションが極端に負荷が高くなるためです。

メッセージの量を多く受け取り、変に GC が走りまくっているような場合は off_heap を試してみるのも良いでしょう。