BackEnd

Go 1.24で追加されたweak pointer

投稿日:2025年4月16日 更新日:

はじめに

前回の記事では、Go 1.24での変更点についていくつか列挙し、その中でomitzeroタグについて紹介しました。

今回はその続きとして、weak pointerに付いて書きたいと思います。

weak pointerとは

まず初めに、weak pointerについて簡単に説明します。

変数への参照にはいくつか種類があり、その中でも強参照(strong reference)と弱参照(weak reference)は様々なプログラミング言語で用いられています。

Goにおいては、強参照の格納場所をpointerと呼び、今回新たに追加された弱参照の格納場所をweak pointerと呼びます。

pointerとweak pointer

これら2つ(strongかweakか)は読んで字のごとく、参照の強さが異なります。

具体的にどう違うかというと、pointerによる参照が残っている場合はGCの対象にはならないため、変数のスコープが終了するまではメモリ上に残ります。

それとは逆に、weak pointerによる参照が残っている場合ではGCの対象になる場合があります。

つまり、weak pointerによる参照先は、知らないうちにメモリ上から開放される可能性があります。

weak pointerが有効なケース

weak pointerが力を発揮するものとして真っ先に挙げられるのがキャッシュです。

pointerでキャッシュしている場合、明示的に参照先をnilにするなどして参照元をなくさない限りメモリ上に残り続けるため、キャッシュが増えれば増えるほどメモリを圧迫していきます。

pointerの代わりにweak pointerを使えば、メモリを使用する量が一定を超えれば自動的に開放されるため、メモリをより効率的に使うことができます。

weak pointerを使う上での注意点

このように使い方によっては非常に強力なweak pointerですが、いくつか注意する点があります。

  1. 参照先の値を取得する際には必ずnilチェックする
  2. weak pointerを多様しない
  3. 複数のgoroutineから参照される場合では、ロックやsync.Mapを使う

1については、いつGCによって参照先が開放されるかわからないので、値を参照する前には参照先がnilでないか必ずチェックすることが望ましいです。

2については、weak pointerは特定の役割においては強力ですが、何にでも使えるようなものではないので、多様は禁物です。

3については、pointerにも言えることですが、goroutineなどで同時に更新されるような場合では注意が必要です。

weak pointerを使ったキャッシュの実装

それでは、実際にweak pointerを使って簡単なキャッシュプログラムを書いてみます。

コードの全体像

まずは、コード全体をお見せします。

このコードを実行すると以下のようなログが出力されます。

このプログラムでは、始めにキャッシュを作成し、キャッシュに値をセットします。

その後、goroutineを起動し、その中の無限ループ内でキャッシュから値の取得を試みます。

キャッシュから値を取得できた場合はそれを出力し、取得できなかった場合はループを抜けます。

同時に無限ループ内の中でカウントアップし、3回目の実行時にGCを呼び出します。

GCが呼び出された事により、キャッシュ内のweak pointerで参照していたメモリが開放されるため、それ以降はキャッシュから値を取得できなくなり、goroutineが終了します。

weak pointerの作成

weak pointerの作成は weak.Make 関数で行うことができます。

引数に渡す値は、pointerであれば何でも渡すことができます。

weak pointerから値を取得する

weak pointerからの値の取得は、 Value メソッドを使って行います。

この際、参照先がnilでないか必ずチェックするようにしましょう。

さいごに

weak pointerの概要と使い方について紹介しました。

おすすめ書籍

シリコンバレー一流プログラマーが教える Goプロフェッショナル大全 実践!Go言語とgRPCで学ぶマイクロサービス開発 (設計技術シリーズ126) 効率的なGo ―データ指向によるGoアプリケーションの性能最適化

blog-page_footer_336




blog-page_footer_336




-BackEnd
-

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。

関連記事

Go言語

Go言語、ゴルーチン(goroutine)で並列処理を

はじめに こんにちは、nukkyです。Go連載7回目を担当させていただきます。 プログラムを書く上ではなかなか避けては通れない非同期処理について今回は記事にしたいと思います。 ゴルーチン Goにはスレ ...

Pythonコードが育っても品質を維持するツールを考える[Ruff Pyright]

はじめに Pythonでアプリケーション開発をするとなると、ちょっとしたPythonスクリプトを書くのとは違った難しさがあります。素のPythonは、スクリプト言語らしい自由さを持っていますが、その状 ...

laravel logo

Laravelで非同期実行する

はじめに バックエンドの実装に関して、時間がかかる処理を行う場合、非同期に処理したいケースがあると思います。今回はLaravelで非同期に処理するための手軽な方法を紹介します。 動作環境 本記事ではP ...

laravel logo

Laravelでテストコードを書くには? Featureテスト/Unitテスト

はじめに Laravelでは、PHPUnitが標準で組み込まれているので、プロジェクトのセットアップ完了後、すぐにテストコードを書き始めることができます。この記事では、Featureテストを使用したW ...

laravel logo

Laravel-debugerbarを使ってみた

はじめに 今更ですが、Laravel開発時に便利なツールを紹介したいと思います。開発時に知りたい情報が網羅的に確認出来ます。 開発効率が上がると思うのでまだ使っていない方は試してみてください。 インス ...

フォロー

blog-page_side_responsive

2025年4月
日 月 火 水 木 金 土
 12345
6789101112
13141516171819
20212223242526
27282930  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。