BEAMとJVMの基本的な機能/アーキテクチャの違いは何ですか?
- はい、わかっています。1つは元々Javaを中心に構築され、もう1つはerlangを中心に構築されました。
- JVMを(ある程度)理解していて、それらの構造を比較したい
- たとえば、JVMにはグローバルGCが1つあり、BEAMにはプロセスごとに1つあることがわかっています。
BEAMとJVMの基本的な機能/アーキテクチャの違いは何ですか?
まず第一に、Beamはレジスターマシンであり、スタックマシンではありません。WAM for Prologと同様に、通常のレジスタ(Cで配列として実装)である「Xレジスタ」と、ローカル関数アクティベーションレコード(「コールフレーム」)のスロットの名前である「Yレジスタ」を使用します。スタック上。スタック操作命令はありません。
次に、ヒープメモリの数ワードをすばやく割り当てる、ヒープ上のタプルやその他のデータ構造を初期化する、タプルの要素を選択するなどの手順があります。JVMはオブジェクトに焦点を当てており、非表示にする「新しい」操作があります。メモリ割り当てと基本的な初期化の詳細。
BEAMには、プロセスの「リダクションカウンター」をデクリメントし、別のプロセスを実行するために譲歩する時期かどうかを判断するための命令があります。一方、JVMにはスレッドの同期命令があります。
重要な違いの1つは、BEAMにはJVMにない末尾呼び出し命令があることです。
最後に、BEAMとJVMの両方で、オブジェクトファイルで使用される命令セットは実際にはトランスポート形式にすぎません。BEAMエミュレーターは、ファイルからの命令を、多くの最適化された特殊なケースの命令(リリースごとに変更できる)を含む内部バージョンに書き換えます。または、ネイティブコードにコンパイルすることもできます。ほとんどのJVMは同じことをします。
その他の興味深い点は次のとおりです。
プロセスはBEAM市民であり、VM自体によって管理され、JVMはその管理をOSに委任します。これにより、BEAMは非常に迅速に管理(作成、削除、コンテキストスイッチなど)できるため、妥当なマシン上の数百のJavaスレッドに対して、数十万のプロセスを管理できます。
BEAMでは、プロセス間通信はメッセージ交換に基づいており、競合状態につながる可能性のあるすべてではないにしてもほとんどの状況を排除します。Javaでは、スレッドを同期する必要がありますが、これは困難でバグが発生しやすいものです。
重要な点の1つは、ガベージコレクションは、JVMのグローバルプロセスであるのに対し、BEAMではプロセスごとに実行されるということです。影響は、JVM上のGCがVM全体を数秒間フリーズする可能性がある一方で、BEAMでは各プロセスが他のプロセスに影響を与えることなくGCに実行操作(削減)の一部を提供する必要があることです。
最近、 JVM言語用のVertX ( Akkaはよくわかりませんが、そうだと思います)のようないくつかの新しいライブラリは、問題1と2を解決するために、同様のプロセス動作を実装し始めました。ただし、ライブラリを使用すると簡単に解決できます。