JAVA(Android)のメモリ管理
まずiOS(Cocoa Touch, Objective-C)とWindows(Silverlight/WinRT, C#)の場合を考える。iOSの場合はdelegate, KVO, NSNotificationCenterがある。
2011-09-18 16:09:41Windowsの場合はC#であればdelegateとそれをさらに拡張したeventの仕組みで一発解決する。これが一対一と一対多を兼ねる。参照先をweak referenceするから循環参照の危険もない。
2011-09-18 16:10:53多対多はどうすればいいのか正直わからないのだが、そういう仕組みがあるらしいということは聞いている。最も、たいていの場合は一対多で事足りるけど。
2011-09-18 16:12:23最後に問題のJavaだ。Androidを想定する。一対一の場合はInterfaceとそれを継承したクラスのインスタンスを渡すことで通知を行うのがほぼ通例だ。一対多は全くわからない。多対多もさっぱりだ。
2011-09-18 16:13:12一対多と多対多は後ほど考えるとして、まず一対一。さっきのInterfaceとそれを継承したインスタンス渡しというのはiOSのdelegateの実装と基本同じである。問題はそこにメモリの話が付いてくる。iOSにはweak referenceがある。しかしAndroidの場合は?
2011-09-18 16:15:10当然Javaにもweak referenceはある。java.lang.ref.WeakReference<T>がそれだ。きちんとそれを使って構築されているのだろうか。
2011-09-18 16:16:35さらに問題になるのが、そういうdelegateがweak referenceとして渡したインスタンスを保持しているのか、それとも保持していない(すぐに使って捨てる)のかが明示的になっているケースが見当たらない(俺調べ)という点だ。iOSの場合はweak referenceが自明。
2011-09-18 16:18:17weak referenceなら自分がそのインスタンスを責任持って抱えないと(抱える仕組みを使わないと)GCされて死ぬ。そうでないなら自分が責任持ってそのインスタンスを使用後破棄しないとメモリリークして死ぬ(気がする。gcが循環参照を綺麗に捨ててくれるなら別)。
2011-09-18 16:19:08@akisutesama Androidは参照カウンタじゃないからそこが循環参照してても別にいいんじゃないの?ダメなのですか?
2011-09-18 16:20:04というメモリ周りの話がまるで表に出てきて見えないのがJavaのすげぇ困ったところなのである。そこで質問。JVMは循環参照してても全然問題なくgcしてくれるから気にしないで通常の強参照(フィールド)に突っ込んじゃって全然OKなのか、否か。この程度のこともわからん程度すすんません><
2011-09-18 16:21:24ここで、もし答えが「大丈夫だ、問題ない」であったとしても、だ。強参照同士で相互ループしているだけならいい。それら両方が死んだら死ぬのだから。しかしもし万が一何かの間違いでほぼ永続するインスタンスからそれらのどちらかが強参照されてしまったら?・・・死亡確定。ってこれはどこでも同じか
2011-09-18 16:22:33@akisutesama いや、Androidで例外はあるのかもしれないけど、循環参照しててもルートから辿れないオブジェクトはGCのタイミングで破棄されるよ。JVMっていうかGCのアルゴリズムの話かな。
2011-09-18 16:28:03あと、匿名クラスのインスタンスとか、内部クラスとかstatic内部クラスとかのメモリの絡みが一マイクロメートルもわからん。俺の情弱認識では、内部クラスは親クラスのインスタンスに対して強参照を持っている。匿名クラスは匿名クラスを生成したクラスが内部クラスを作ったのと同じ状態になる。
2011-09-18 16:28:56@akisutesama Javaはリファレンスカウンタ方式じゃないので大丈夫ですよ。リファレンスカウンタだと循環参照だと解放しても0にならないって問題がおきますが、JavaのGCはルート集合から辿れない物は全て破棄なんで、循環してても関係ないです。
2011-09-18 16:30:40ということでまとめ。Javaの場合は強参照とか気にする必要がありません。インスタンス渡せばおk。たとえ相互参照していてもgc様が綺麗に解決してくれますひゃっほう。やったねたえちゃん!
2011-09-18 16:32:20とか考えながらjava.lang.refを見ていたらWeakの他にSoftとかPhantomとかあった。どういうことなの・・・
2011-09-18 16:32:46Effective Javaはお作法の本であってメモリ関連のお話はしてくれないのでありました。ガハァ。
2011-09-18 16:35:32こんなとき佐藤太一がいてくれれば・・・「JVMのソース嫁」とアドバイスをしてくれるものを・・・
2011-09-18 16:36:53