JNI提供了C程序和Java程序的互操作机制。通常每个进程C进程只能启动一个JVM实例。在工程中,发现对于C程序fork派生的父子进程,可能存在以下潜在的问题:
条件:
1、C程序中创建了JVM实例。
2、C程序fork出子进程。
3、子进程中调用Java方法,进行了某些特定操作,如打开了文件流并没有关闭;或new了apache.axis的Service对象;或调用了某些JavaBean的toXml方法。
结果:
子进程可能会挂起。用strace查看,子进程阻塞在了futex系统调用。
futex是Linux的一种同步机制,在2.5.7内核引入。经测试,对于RHEL AS3(Kernel 2.4),此问题偶然发生(也挂起在futex系统调用,暂不知道2.4中为什么有futex);对于RHEL AS4或Ubuntu 7.10(Kernel 2.6),此问题几乎一定发生。
我们猜测是Java中对文件操作的同步机制与futex有冲突,造成了死锁。具体原因有待分析,目前需要尽量避免在使用JNI的程序中进行上述操作。