Skip to content

新しいメモリマネージャーへの移行

レガシーメモリマネージャーのサポートは、Kotlin 1.9.20 で完全に削除されました。Kotlin 1.7.20 以降でデフォルトで有効になっている現在のメモリモデルにプロジェクトを移行してください。

このガイドでは、新しい Kotlin/Native メモリマネージャーをレガシーなものと比較し、プロジェクトの移行方法について説明します。

新しいメモリマネージャーにおける最も顕著な変更点は、オブジェクト共有に関する制限が解除されたことです。スレッド間でオブジェクトを共有するためにオブジェクトをフリーズ(freeze)する必要はありません。具体的には以下の通りです:

  • トップレベルのプロパティは、@SharedImmutable を使用せずに任意のスレッドからアクセスおよび変更できます。
  • インターオペラビリティ(interop)を介して渡されるオブジェクトは、フリーズすることなく任意のスレッドからアクセスおよび変更できます。
  • Worker.executeAfter は、オペレーションをフリーズさせる必要がなくなりました。
  • Worker.execute は、プロデューサーが分離されたオブジェクトサブグラフ(isolated object subgraph)を返す必要がなくなりました。
  • AtomicReference および FreezableAtomicReference を含む循環参照は、メモリリークを引き起こしません。

オブジェクト共有が容易になったこと以外にも、新しいメモリマネージャーにはいくつかの大きな変更点があります:

  • グローバルプロパティは、それが定義されているファイルに最初にアクセスしたときに遅延初期化されます。以前は、グローバルプロパティはプログラムの起動時に初期化されていました。回避策として、プログラムの開始時に初期化する必要があるプロパティには @EagerInitialization アノテーションを付けることができます。使用する前に、そのドキュメントを確認してください。
  • by lazy {} プロパティはスレッドセーフモードをサポートし、制限のない再帰(unbounded recursion)は処理しません。
  • Worker.executeAfter 内の operation から発生した例外は、他のランタイム部分と同様に処理されます。具体的には、ユーザー定義の未処理例外フック(unhandled exception hook)の実行を試みるか、フックが見つからない、またはフック自体が例外で失敗した場合はプログラムを終了します。
  • フリーズ(Freezing)は非推奨となり、常に無効化されます。

レガシーメモリマネージャーからプロジェクトを移行するには、以下のガイドラインに従ってください:

Kotlin のアップデート

新しい Kotlin/Native メモリマネージャーは、Kotlin 1.7.20 以降、デフォルトで有効になっています。Kotlin のバージョンを確認し、必要に応じて最新バージョンにアップデートしてください。

依存関係のアップデート

kotlinx.coroutines

バージョン 1.6.0 以降にアップデートしてください。native-mt サフィックスが付いたバージョンは使用しないでください。

新しいメモリマネージャーに関して、留意すべきいくつかの特記事項もあります:

  • フリーズが不要になったため、すべての一般的なプリミティブ(チャネル、フロー、コルーチン)は Worker の境界を越えて動作します。
  • Dispatchers.Default は、Linux および Windows では Worker のプール、Apple ターゲットではグローバルキューによってバックアップされます。
  • Worker によってバックアップされるコルーチンディスパッチャを作成するには、newSingleThreadContext を使用します。
  • N 個の Worker のプールによってバックアップされるコルーチンディスパッチャを作成するには、newFixedThreadPoolContext を使用します。
  • Dispatchers.Main は、Darwin ではメインキュー、その他のプラットフォームではスタンドアロンの Worker によってバックアップされます。
Ktor
バージョン 2.0 以降にアップデートしてください。
その他の依存関係

大部分のライブラリは変更なしで動作するはずですが、例外がある場合があります。

依存関係を最新バージョンに更新し、レガシーメモリマネージャー用と新しいメモリマネージャー用のライブラリバージョンに違いがないことを確認してください。

コードのアップデート

新しいメモリマネージャーをサポートするために、影響を受ける API の使用箇所を削除してください:

旧 API対応方法
@SharedImmutableすべての使用箇所を削除できます。ただし、新しいメモリマネージャーでこの API を使用しても警告は出ません。
FreezableAtomicReference クラス代わりに AtomicReference を使用してください。
FreezingException クラスすべての使用箇所を削除してください。
InvalidMutabilityException クラスすべての使用箇所を削除してください。
IncorrectDereferenceException クラスすべての使用箇所を削除してください。
freeze() 関数すべての使用箇所を削除してください。
isFrozen プロパティすべての使用箇所を削除できます。フリーズは非推奨であるため、このプロパティは常に false を返します。
ensureNeverFrozen() 関数すべての使用箇所を削除してください。
atomicLazy() 関数代わりに lazy() を使用してください。
MutableData クラス代わりに任意の通常のコレクションを使用してください。
WorkerBoundReference<out T : Any> クラスT を直接使用してください。
DetachedObjectGraph<T> クラスT を直接使用してください。C インターオペラビリティを介して値を渡すには、StableRef クラスを使用してください。

次のステップ