如何在Java中使用posix_spawn()

时间:2011-04-11 17:31:33

标签: java solaris

我继承了使用ProcessBuilder.start()在Solaris 10服务器上执行脚本的遗留应用程序。

不幸的是,由于内存问题,此脚本调用失败,如文档here

所示

Oracle的建议是使用posix_spawn(),因为ProcessBuilder.start()使用fork/exec

我无法找到任何示例(例如,如何调用"myScript.sh"

在Java中使用posix_spawn(),甚至是所需的包。

请问,请给我一个关于如何在Java中使用posix_spawn()的简单示例?

4 个答案:

答案 0 :(得分:3)

另一种不需要JNI的方法是创建一个单独的“进程生成器”应用程序。我可能会让这个应用程序公开一个RMI接口,并创建一个包装器对象,它是ProcessBuilder的替代品。

您可能还想考虑让这个“spawner”应用程序成为启动旧应用程序的东西。

答案 1 :(得分:2)

您首先需要熟悉JNI。学习如何从Java代码调用本机例程。完成后 - 您可以查看this示例,看看它是否有助于解决您的问题。你特别感兴趣的是:

if( (RC=posix_spawn(&pid, spawnedArgs[0], NULL, NULL, spawnedArgs, NULL)) !=0 ){
    printf("Error while executing posix_spawn(), Return code from posix_spawn()=%d",RC);

}

答案 2 :(得分:1)

更简单的解决方案是保持代码不变,只需向服务器添加更多虚拟内存。

即:

mkfile 2g /somewhere/swap-1
swap -a /somewhere/swap-1

编辑:澄清问题中的链接现在已被破坏:

问题是由于JVM被分叉而导致虚拟内存系统出现问题。例如,假设JVM使用2 GB的VM,则fork需要额外的2 GB VM才能在Solaris上成功运行。这里没有涉及分页,只是内存预留。与默认情况下过度使用内存的Linux内核不同,Solaris确保分配的内存由RAM或交换支持。由于没有足够的可用交换,fork失败了。扩展交换允许fork成功而不会对性能产生任何影响。在fork之后,exec“取消”这个2GB的RAM并恢复到与posix_spawn相同的情况。

有关Solaris和其他操作系统下的内存分配的说明,另请参阅此page

答案 3 :(得分:1)

最新版本的Java 7和8在内部支持posix_spawn

命令行选项

-Djdk.lang.Process.launchMechanism=POSIX_SPAWN

或在运行时启用

System.setProperty("jdk.lang.Process.launchMechanism", "POSIX_SPAWN");

我很遗憾默认情况下启用了哪个Java版本/操作系统组合,但我确定您可以快速测试并快速找到设置此选项是否有所作为。

作为参考,要返回旧fork方法,只需使用

即可
-Djdk.lang.Process.launchMechanism=fork

要证明在JVM版本中是否遵守此选项,请使用

-Djdk.lang.Process.launchMechanism=dummy

您下次exec时会收到错误消息。这样您就知道JVM正在接收此选项。