Perlテックブログ

ITエンジニアの成長意欲を刺激する技術考察、モジュール開発の日記。Perlイベントや国内や海外のPerlの記事の紹介。

SPVMのメモリ管理 - モータルオブジェクトの実装

SPVMは静的な型を持つ言語なんだけれど、オブジェクトのメモリ管理は、Perlにならって、リファレンスカウント方式GCなんだ。

リファレンスカウント方式というのは、オブジェクトの生存期間を、他のオブジェクトからの参照がなくなった時点で、終わりとするものなんだ。

最初に参照が発生した時点で、リファレンスカウントを1増やす。他のオブジェクトから参照されるとさらに1増やす。逆に、所有しているオブジェクトが解放されると、1減らす。そして、最終的に0になった時点で、オブジェクトを解放する。

リファレンスカウント方式のメリットとデメリット

リファレンスカウントGCと世代別GCの特徴を表にしてみる。

リファレンスカウントGC 世代別GC
シングルスレッドで管理できる 解放用のスレッドが必要
レスポンスタイム高スループット レスポンスタイム低、スループット
循環参照の解決は弱参照が必要 循環参照は自動的に解決
デストラクタのタイミングが決まる デストラクタのタイミングは不確定
マルチスレッドとの親和性が悪い マルチスレッドとの親和性が良い
消費メモリは少ない 消費メモリは大きい

この表はちょうどJavaPerlの性能の対比のようにもなっている。スループットが高く、マルチスレッドができるJava。省メモリで、レスポンスタイムが速く、シングルスレッドのPerl。(Perlは事実上マルチスレッドは非推奨ということになっている。)

世代別GCは、Full GCが発生したタイミングで、レスポンスタイムが落ちるので、ここで詰まると、全体のレスポンスタイムを引っ張ることになるから、JavaでWebアプリを作る場合は、この部分を手動で調整してやらなければならないことが多い。

Perlの場合は、デフォルトで大丈夫。スコープ単位で小さな解放が何回も行われるから、レスポンスタイムについては、心配は少ない。スループットを出そうと思うと少し工夫がいる。

SPVMのモータルオブジェクトの実装

と、ここで話は変わって、現在僕は、SPVMのモータルオブジェクトの実装に取り組んでいる。モータルオブジェクトというのは、スコープの終わりで、自動的にリファレンスカウントが1減らされ、0になった場合は、自動的にオブジェクトが解放されるオブジェクトのことだ。

SPVMの言語としてのモータルオブジェクトの実装は終わっているんだけれど、これをC言語APIレベルで、同一の実装ができないかと試行錯誤中。

PerlはXSでは常に、メモリについて意識しないといけない。新しくオブジェクトを作る場合は、必ず明示的に、オブジェクトをモータルにしてあげないといけない。これが非常に厄介だ。

SPVMでは、モータルにすることを意識しないで、オブジェクトを生成する仕組みを提供しようとしている。今週は、この仕組みを作成する。メモリ管理を意識しないで、C/C++と連携できるようにすることが目標だ。