KH-FDPL に関するメモ-0007

  • (by K, 2015.02.16)

KH-FDPLの特徴(3) - オブジェクト(変数)の寿命管理

  • (3-1) C++ではnewでオブジェクトを作ってdeleteで破棄していました。また自動変数(スタック上にとられる変数)はスコープから抜けるときに自動でデストラクタが呼び出されていました。
    • この自動変数の挙動は便利で分かりやすくて深刻なメモリリークバグも起こりにくいと思いますが、自分でnewして作ったオブジェクトについてはdeleteを呼び忘れたりしてメモリリークバグの大きな原因となっています。
  • (3-2) JavaではGC(ガーベージコレクション)を採用し、プログラマがdeleteしないでもいいようにしました。
    • これは一見すると非常にかっこいいのですが、実際は処理系が未使用のオブジェクトをうまく検出できずにメモリリークしてしまったり(特に循環参照などが起こるとリークしやすい)、full-GCが始まるとプログラムがしばらくの間とまってしまう問題があります。
    • GCは多くの場合ではプログラマを寿命管理から解放してくれます。しかしそのせいでこれに配慮しないことに慣れてしまい、リークやfull-GCに悩まされ始めた時にどうしていいかわからなくて途方に暮れることになります。これはあまり教育的な仕様とは言えないでしょう。
  • (3-3) これらに対する比較的新しい方法として、autorelease方式があります。iOSのObjective-Cで使われています。
    • これはとても良い方法だと思いました。KH-FDPLでも最初はこの方法をそのまま取り入れようと思っていたくらいです。
    • ただautoreleaseしない場合に、retainやreleaseで参照カウンタを管理しなければいけません。その部分の難易度が従来と大差ないと思いました。ここで間違えればやはりメモリリークしてしまいます。
  • (3-4) KH-FDPLの方式。
    • KH-FDPLは参照カウンタを持ちません。結局こういうものをプログラマに管理させていると、永久にメモリリーク問題はなくならないと思うからです。
    • 短期間で作って壊すようなオブジェクトは、まさにautoreleaseと同じ方法で管理します。次回の回収時に回収されるプールがあるので、そこに登録するわけです。
    • そしてそれより長く生き残るオブジェクトに関しては、どのプールに所属するかを「new時に」指定します。どんなプログラムも、最低一つのプールを持っていますし、関数呼び出しをすればそのたびにプールが作られます。それらの中のどのプールに所属するのかをnew時に指定すればいいのです。
    • これにより、そのプールが回収されるときに必ずオブジェクトは回収されます。リークしません。
    • もし寿命を変更したくなれば、あとから所属するプールを変更すればいいです。それで問題ありません。
    • プールを指定するなんて言うとややこしく聞こえますが、ファイルを作るときに所属パスを指定するのと同じくらいの感覚です。何も指定しなければ、次回回収プールがデフォルトで選ばれます(autorelease相当)。関数の戻り値用のオブジェクトは、次々回回収プールがデフォルトになります。
    • そもそもオブジェクトを作るときが、もっともオブジェクトの寿命について考えているときでもあるのです。オブジェクトを作るときは、そのオブジェクトを何のために作るのかわかっていますし(目的)、だからいついらなくなるのかもわかっているのです。
  • (3-5) KH-FDPLはオブジェクトが基本的に永続性なので、メモリリークは非常に深刻です。
    • だからこんなにリークさせない仕組みにこだわっているのです。
    • KH-FDPLでリークを起こしてしまったら、それは再起動後にも残るので、放置していると永久に残ります。他の言語環境ならリークしても再起動すれば済みますが、KH-FDPLではそうは行かないわけです。まあ自分でせっせとリークしたオブジェクトを特定して消していけばいいといえばそれまでですが、それよりはリークを起こさない仕組みを考えるほうが建設的だと思います。

こめんと欄

  • いまのobjective-cはarcというコンパイラが参寿命管理する仕組みがあるのでobjective-cの世界の中だけなら自分で参照カウンタ管理しなくても循環参照以外でリークすることはほとんどないです -- neri 2015-02-17 (火) 10:29:33
  • おおすごい!そう、arcっていうのがあるのはうわさに聞いていたけど詳細は知りませんでした。循環参照以外は問題なしっていうのは、JavaのGCと同等の条件ですが、でもObjective-Cだとfull-GCとかで止まったりはしないので、圧倒的に優秀ですね! -- K 2015-02-17 (火) 14:26:24

コメントお名前NameLink

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2015-02-17 (火) 14:26:24 (3358d)