java.lang.OutOfMemoryError extends java.lang.Error2008年06月11日 16時12分51秒

Java の OutOfMemoryError は Error を拡張している。少々長くなるが、以下が java.lang.Error からの引用だ。
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.

A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur.

Exception は catch 出来るが、Error は catch 出来ない。Java によると Error は「例外処理できない深刻なエラー」とある。しかし、メモリ不足は処理できないエラーではない。むしろ、エラーの処理を正しく処理しようとするのなら、メモリ不足を正しく処理する必要がある。特に無停止系の処理をするのには、このような状況を正しく処理しないのは、むしろ好ましくない。

これを catch 出来ないというのは深刻だ。つまり、何らかの処理が意図しないところで停止し、内部状態が不明な事に陥り兼ねない。確かに、メモリ不足の処理を必要としないプログラムも多い。メモリ搭載量も年々増し、普段はメモリ不足になることも少ない。

そんなに正確無比な処理を必要としなくても問題は起こる。画像処理や、データベースの処理などを WeakHashMap などでキャッシュすることを考えよう。ImageMagick の display の様な画像を表示する場合を考えよう。画像が大きくなると、再描画する時の為に、キャッシュを使いたくもなる。そこで、WeakHashMap を用いて、そこに無かった場合には、画像のアイコンを作成する。もし、OutOfMemoryError が出るのであれば、この時だ。既に画像のキャッシュに大量にメモリを使っていて、新たに画像オブジェクトが生成できない。一時的にキャッシュを破棄すれば、十分なメモリが確保出来る状態になるが、メモリ不足を検知する手段が無い。つまり、表示できるはずの画像が、表示できないことになる。

Java のポインタを無くすという試みは、悪くは無い。しかし、それだからといって、計算機からの警告すら寸断するのは頂けない。使いはするが、Java を好きになれない理由の一つだ。