Javaの中のシグナル

straceやtrussでJavaVMの挙動を調べると、頻繁にSIGSEGVが発生していることがわかります。
で、SIGSEGVが発生しても正常に処理を継続する場合と、abortしてしまう場合とがあって、
どういう理由で分かれるのかが以前から疑問だったのですが、最近、やっと分かりました。
(詳しくはhttp://sdc.sun.co.jp/java/j2se/private/jdk50_ts_guide-jp.pdfを参照)


どうやら、HotSpotコンパイラの最適化機能によって、ポインタのNULLチェックが省略されているようです。
この場合、SIGSEGVが発生すると、内部でNullPointerExceptionに変換されてthrowされる事になります。
HotSpotコンパイラが生成したコード以外の場所でSIGSEGVが発生した場合、Java VMは致命的エラーログ(hs_err[PID].logっていうファイル)を出力して終了します。


逆に言うと、「NullPointerExceptionの裏では"Segmentation Fault"が発生している」、という事ですね。
やっぱりNullPointerExceptionなんて、起こすもんじゃないな、と。


他にもSIGBUS、SIGFPEなどもJava VM内部での制御に使用しているとの事。
これらのシグナルのハンドラを書き換えているプログラムをJavaから呼び出すのは、やめておいた方が良いですね。


それでもシグナルハンドリングをしたい人は、「シグナル連鎖機能」なるものを使え、と書いてあります。
どういうものかは私も知らないのですが、そのうち、試してみたいところです。