RubyとPythonの違いからガベージコレクタを理解する

http://patshaughnessy.net/2013/10/24/visualizing-garbage-collection-in-ruby-and-python

1 comment | 0 points | by Jshiike 3年弱前


Jshiike 3年弱前 | ▲upvoteする | link

Pat Shaughnessyが、ブタペストで開催されたRUPY2013でのプレゼンの前半を自らのブログで紹介しています。


ガベージコレクタは、「ゴミを集める」という行為だけでなく、「新しいオブジェクトのためにメモリをあてがう。」「不要なオブジェクトを見つける」「不要なオブジェクトからメモリを取り戻す。」という、人間の心臓が血液を浄化するような働きをしている。


この簡単なコードサンプルを見ると、RubyとPythonの記述はよく似ているが、それぞれの言語の内部でのインプリの仕組みは違う。


1) Rubyのメモリ


Rubyは、コードが実行される前に、数千のオブジェクトを先につくり、それをリンクされたfree listに置く。[] そして、上記のコードサンプルにあるNode.new (1)がコールされると、オブジェクトを一つfree listから取って渡してくれる = コードで利用されるアクティブなオブジェクトになる。[](もちろん実際には他の役割を担うオブジェクトもあって、もっと複雑だが、話しをシンプルにするためにこの図の考え方を使って説明している。)


次にNode.newが再びコールされると、二つ目のオブジェクトをfree listから渡してくれる。 [] このMRIの仕組みは、1960年にJohn McCarthyがLispの開発の過程でつくったアルゴリズムを用いている。


2) Pythonのメモリ


Pythonも、リストのためにオブジェクトを再利用するのでfree listの仕組みを内部ではもっているが、通常はRubyとは違うメモリの扱いをする。PythonはオブジェクトをつくったらすぐにOSにメモリを要求する。[図](Pythonは実際、OSヒープ上に追加の抽象化レイヤをつくるメモリ適用システムをインプリするが、今回はその詳細の説明は割愛。)二つ目のオブジェクトをつくる場合も同様に、OSにメモリを要求する。[]


3) Rubyは未利用のオブジェクトを放置


Rubyでオブジェクトが次々つくられると、free listの残りが少なくなる。[] n1に新しいバリューがアサインされると、古いバリューが残ったオブジェクトが放置されていることに注目してほしい。[]


4) Pythonは未利用のオブジェクトを掃除


PythonではオブジェクトのC構造の内部に参照カウントという整数をもち、初期数値は1。1という数字は一つのポインターが指す、参照されているという意味。[] 新しいnodeがつくられて、元のnodeが不要になると、そこの参照カウントがゼロになる。[] すぐにPythonはそのメモリをOSに戻す。[] 参照カウンターは、同じ1960年にGeorgeCollinsが生み出したアルゴリズム。次に、n2がn1と同じnodeを参照すると、従前にn2が参照していたnodeは掃除される。 []


5) RubyのMark & Sweepアルゴリズム


Rubyのゴミが溜まり続ける構造では、いずれfree listが枯渇する。そうなるとRubyはアプリを止め、全体をループし、メモリがあてられているオブジェクトにマークをつける。[] 内部的にはRubyは、マークされているか、そうでないかをfree bitmapで管理している。 [] Rubyは、unix copy-on-writeの最適化を利用するためbitmapを別のメモリ場所に保管している。


マークされていないオブジェクトは掃除される。[] Rubyは、一連の作業においてオブジェクトをコピーせずに、内部のポインターを調整して新しいlink listを作成することで、オブジェクトをリストに返しているので、作業はかなり短い時間で完了する。


6) Mark & Sweepと参照カウント


参照カウントをガベージコレクタのアルゴリズムに採用しない言語がある理由は、


  • 各オブジェクトの内部に参照カウントを置くスペースを確保したり、変数/参照を上下変化させるオペーレーションなど、この手法のインプリは難易度が高い。

  • Pythonは頻度高く参照カウントを更新していて、例えば大きなデータ構造の利用をやめると、参照カウントの修正が一気に、かつかなり複雑な作業になり、アプリが遅くなる可能性がある。

  • 参照カウントは、巡回する循環参照のデータ構造には使えない。(次回詳細説明)

その2はこちら


ワザノバ TOP100 アクセスランキング [8/25-10/12]



#ruby #python #ガベージコレクタ

Back