Metalsが重いなと思ったときに確認するべきこと

私はZedというエディターで普段Scalaのコードを書いています。Scalaの言語サーバとして代表的なものにMetalsというものがあります。

ZedにはMetals向けの拡張機能があり、これを導入することでZedでもScalaのコード支援を受けることができます。

appare45.hatenablog.com

しかし、私は長らくMetalsが異常に重い問題に苦しめられてきました。そこで2025年のお正月を利用してその原因を調べました。

この記事はMetalsを直接使っている珍しい人向けの記事です、VSCodeではまた違う設定がある気がするので参考程度にしてください

ArmアーキテクチャのMetalsが動いているか確認する

私はAppleのM1というCPUのパソコンを利用しています。M1はX86ではなくArmアーキテクチャのCPUですが、Macの場合はRossetaを使うことで、X86アーキテクチャのソフトウェアを動かすことができます。

もちろん、Armアーキテクチャのソフトウェアを動かしたほうがオーバーヘッドが少なくパフォーマンスも向上します。

Metalsのインストールによく使われるCoursierには、Arm版も用意されていますが、Homebrew経由でインストールした場合はデフォルトでX86版がインストールされるという罠があります。*1

Metalsが現在どのアーキテクチャで動作しているかはps aux | grep metalsで表示されるPIDをアクティビティモニタで調べたときに「種類」にIntelと表示される場合はX86アーキテクチャのRosettaによるエミュレーションで起動しています。

この場合はArmアーキテクチャのものを再インストールすることをおすすめします。

cs uninstall --all # Coursierでインストールされたパッケージをすべてアンインストールする
brew uninstall coursier/formulas/coursier # Homebrewから削除
# Arm版をインストール
curl -fL https://github.com/VirtusLab/coursier-m1/releases/latest/download/cs-aarch64-apple-darwin.gz | gzip -d > cs
chmod +x cs
./cs setup

Metalsがビルド結果を常に再利用するよう設定する

Scalaではビルドを高速化するためBloopというビルドサーバが使われるのが一般的なようです。

MetalsはBloopにScalaファイルをインポートさせるかどうかを選ぶことができる?*2のですが、Zedではなぜか聞かれないので常にインポートするようLSPを設定します。

{
  "lsp": {
    "metals": {
      "autoImportBuild": "all"
    }
  }
}

Metals/Bloopに割り当てるメモリの量を増やす

Metals・BloopともにJVM上で動作しています。JVMでは動作するアプリケーションに対して割り当てられるメモリ量が決まっており、それを超えた場合はGCが実行されます。

これらの割当量を増やすことで、動作の高速化が期待できます。

{
  "lsp": {
    "metals": {
      "ammoniteJvmProperties": ["-Xmx2G"],
      "bloopJvmProperties": ["-Xmx2G"]
    }
  }
}

以上が自分が行った、Metalsを高速化するためのTipsです。他のも高速化するためのコツなどあれば教えていただければ幸いです。

*1:Armに対応するPRも出ているが放置されていそう

*2:あんまり自分もわかっていない