【Python学習】弱参照に関して学んでみる

Pocket

Pythonチュートリアル第10章、第11章「標準ライブラリめぐり」の内容も今回で最後。

弱参照に関して学習したことをまとめる。

 

弱参照…?

 

Wikipedia に「弱い参照」のページがあった。

参考:「弱い参照 – Wikipedia

内容を自分なりに理解すると、ガベージコレクタですぐに解放できる参照のことと捉えたけれどどうだろう。

すぐに解放できるから「弱い」と表現されているように思われる。

「ガベージコレクタとは何か」、「なぜすぐに解放する必要があるのか」を理解できれば、弱参照が理解できるのではないかな。

ガベージコレクタは、オブジェクト指向言語の基礎のひとつでもあるようなのでしっかり押さえたい。

 

ガベージコレクタ

 

ガベージコレクタは、プログラムが一時確保したメモリリソースのうち、不要になったものを自動解放する機能。

ガベージは「ごみ」、コレクタは「集めるもの」。要するに、ゴミを集めてお掃除してくれる機能である。

Pythonにはガベージコレクタが用意されていて、参照するポインタの数がゼロになったオブジェクトは使われていないと判断して参照を破棄することでメモリ解放を行う(参照カウントアルゴリズムというらしい)。

 

Pythonでオブジェクトを参照するとき、その参照情報はメモリに一時保存される。

不要な参照情報がメモリにいつまでも残っていると、その分使えるメモリ領域が減ることになり、パフォーマンス性能にも影響してくる(メモリリークというんだって)。

メモリがいっぱいだと使えるリソースが限られるのは当然で、多くのメモリリソースを必要とする処理をしようとすると動作が重くなってしまうのは想像できるね。

メモリを使っているのはPythonだけでなく、OSや他の実行中アプリケーションも利用しているし…

昔からメモリリソース解放の必要性は認識されていて、メモリ確保と解放のコードを書いていたらしい。

メモリ解放のコードを実装し忘れたら性能に大きく影響するから大変だよね。

性能の問題はプログラムだけでなく色々な要因があると思うから、ガベージコレクタの実装忘れに気付くのは大変そう。

だからメモリ解放を自動で行う機能が必要だったんじゃないかな。

 

Pythonのガベージコレクタ

 

Python 標準ライブラリのオンラインドキュメントでガベージコレクタの記載を発見。

参考:「29.11. gc – ガベージコレクタインターフェース – Python 3.6.5 ドキュメント

ドキュメントの内容を参考にして、試しに使ってみた。

さて、ガベージコレクタの使い方を簡単に押さえたところで、弱参照を試してみる。

 

弱参照を確かめてみる

 

Python では、weakref モジュールを利用して弱参照を実現する。

Python チュートリアルによれば、weakref モジュールは実際に参照を生成することなく、オブジェクトを追跡するツールを提供してくれるそうだ。

まずは、参照を削除しても参照が消えない状況を作る必要があるのだが…

これが自分でやってみるとうまく状況を作れない!

仕方なく、Python チュートリアルの弱参照の例を参考にして、まずは弱参照を利用せずにガベージコレクタで破棄されない状況を作ってみる。

と、こんな感じで 参照元の変数 a を del したのに、参照できてしまっているのが問題らしい。

ところで gc.garbageも実行してみたけど、こっちは空っぽのままだな…

 

次に弱参照を利用した場合を試してみる。

弱参照を利用した場合としなかった場合とで、明らかな違いが出た。

途中で利用した weakref.WeakValueDictionary() が弱参照を生成する関数らしい。

参考:「8.8. weakref – 弱参照 – Python 3.6.5 ドキュメント

あとは、弱参照の使いどころの判断だな…

是非とも弱参照を使いこなしたいところだけど、プログラミングしてて弱参照を使ったほうがいいなと判断することが、私にはまだできそうにない。

 

まとめ

 

ガベージコレクタの役割と弱参照を生成する方法は分かった。

ただ、参照が破棄できない状況を自分で作ることができず、オブジェクトの参照に関してまだまだ理解が足りないのは問題。

今後、弱参照が必要そうだなというところを認識できる力が全然足りない。

実際に参照が消えずに性能バグで泣いてからもっと理解できるようになるのかな…

うーん、難しい。

今回はこの辺で。

Comments
Pocket

Related posts