2012年07月24日(火)
Java言語のダメな所3大ポイント (2)(Programingの話)
※ あくまでも個人的な感想です。
筆者は本格的なJavaのコーディングは行っておりませんが、C/C++に関しては20年弱ほど職業プログラマーとしてのコーディング歴があり(同じコードを使いまわして20年じゃないよ)、大規模レベルのAndoroidアプリの開発において初めてJava開発環境に関わりました。
2.Java はアプリケーションがヒープ管理する事ができない言語である
Javaでは言語レベルで”ガベージコレクション(通称ガベコレ)”がサポートされており、また使用が強制されるという仕様となっている。
C/C++、アセンブラ等においてはメモリ管理はアプリケーションに任されており、この事によって(主にゲーム機や組み込み系ハードにおける)決して十分では無いメモリーを最大限に生かす事が可能となっている。
が、その反面ポインタを直でアプリが管理する事が必須であるため、削除済みのオブジェクトを正規のオブジェクトとして扱うという検出が困難なバグや、オブジェクトの削除忘れ(メモリリーク)といったお約束のバグが常につきまとう。
ガベコレの詳細な説明は今回はしませんが、アプリケーションが直接メモリーを管理する事ができないという事が言語レベルで前提なので(JNIのレベルまで作りこめば別だが)、上記のようなメモリ関連のバグ自体を発生させる事がJavaではそもそもできないようになっている。
”基本的には”いいことずくめです。
また正直この部分に関しては5~10年後には恐らく意識をすることなくほぼ全員のプログラマーがプログラミングをしている事でしょう(現行の据え置きゲーム機の開発は除いて)。
恐らくGoogle及びAndroidがJavaを選択した理由はここら辺を見越したものではあるかと推測する。
が、以下の状況が満たされない(これには非常に残念ながらAndroid開発環境も含まれる)環境においては尋常ではないレベルで問題が発生する。
OSがストレージへのメモリスワップ及び仮想メモリ等を使用して、実質的にほぼ無限と言ってよいサイズのメモリを提供してくれる場合(あえて数値を出すとすれば一般的なアプリなら数GB程度、HD画質のムービーオーサリングレベルならば数100G~TBレベルは必要か)。
Windowsのような据え置きPC環境においては、現状これはほぼ達成されてると言って良いかという認識。
だが、Android端末のようなスマホに搭載されている物理メモリーは多い機種で1GB、少ない機種に至っては284MB程度なんていうお粗末なものがゴロゴロしていたりする。
また、OSレベルでメモリスワップが提供されてしかるべきであるはずが、Androidに関して言えば何故か恐ろしい事に提供されていません。
で、こういう環境だとむしろガベコレが必須であるという環境がむしろとんでもなく困った事になる訳で。
オブジェクトはいくらでもnewして作れば良い、使用しなくなったオブジェクトに関しては適切なタイミングで削除は行われる。
だがしか~し! メモリが既に足りていない状態で更にオブジェクトをnewしようとするとどうなるのか? >これは例外を吐かれて”以上”となる。
catch すればいいってのはナシで。<このケースにおいては完全にムダなので
メモリが足りない時に仮にオブジェクトを全て管理できていたとしても、削除できないオブジェクトがあればそもそも確保可能なメモリを増やすことができない。
更に言えばJavaではnewと対になるべき構文のdeleteが存在しない言語である。
つまり実質的にメモリ不足例外を吐かれた時点でアプリが仮に落ちなかったとしても対応する術は無く、強制終了と同じ事となる。 参考
更に恐ろしい事にオブジェクト(のサイズ)やメモリーの管理がそもそもできない為、実質的に落ちる時点までメモリーが足りてるのか足りていないのを判断する術も無いのだ。
正直、
こんな環境でアプリケーションを作れ、と?
と言いたくなるような状況だったりする。
まあそうは言っても世の中に大量にAndroidアプリは溢れている訳ではあるんですがね。
そもそもメモリーを食わないようなアプリを作れって事なんだろうけれど。
と、若干Android向けの話になってしまって恐縮ですが、ま、LinuxだろうとWindowsだろうと、据え置きPCでの動作やサーバーPC上で動くようなプログラムに関しては全く問題が無いと言って良い問題だとは思います。(1.と同じ)
そして端末の搭載メモリーがこの先GB、数十GBが当然という状況になるにつれて(そして毎年スマホの平均スペックが上がり続けている限り)、この問題も徐々に解決(?)されていく事はほぼ間違い無いです。
以下独り言。
前に読んだ中島聡さんのエントリーLife is beautiful: Oracleの「Android訴訟」についてひと言で「Java選択した時点で筋が悪い」ってな表現があったんでこんな感じの事かな? と思って改めてエントリーを読んでみたんだけれど、遥かにそれ以前の話だた~よ。
コメント
Rn ( 2012/07/25 03:08)
docomo504時代(30KB)、Javaで定期的にガベコレをコールしてました。
昨今コンバータ程度しかJava使ってないので出来るのかわかりませんが…。
きむ ( 2012/07/25 16:24)
やべ、このシリーズ面白い
パピコン ( 2012/07/26 00:52)
>Rnタソ
上の中島さんのエントリにもありますが、当時のdocomoJavaとは別物っぽい感じがしますね。
もちろん明示的にコールできるなら結構良いのですが。
探してみます。
しかし30KBでJavaって狂ってる組み込み系ですね…。
>きむ
そいつはどうもありがとう~~!
他のシリーズは……orz 聞くまい。
残念ながら比較的まとまってるのは今回がMAXじゃないかと。
パピコン ( 2012/07/28 23:39)
某ゲームエンジンにて、明示的にガベコレを呼べるらしい関数を発見!
が、動作テスト等までは至らず。
合わせてTipsとして書かれてるオブジェクトプールが使えなさ杉ワロタ。
オブジェクトの最大個数管理もせずに延々とnewしつづけるようなコード、今更誰も書かないって。
PC環境ならどうか分からんが(とはいえ深刻なパフォーマンス低下が確実に発生するけどね)。