我目前在Weblogic Java EE项目中工作,其中应用程序不时执行Perl脚本来执行一些批处理作业。在应用程序中,脚本将被调用为
Process p = Runtime.getRuntime().exec(cmdString);
虽然这是一种危险的运行方式,但它正常工作,直到我们要求在for循环下同步执行脚本。经过几次运行,我们得到了
java.io.IOException: Not enough space
因为在执行for循环时OS可能正在耗尽虚拟内存。因此,我们无法在服务器中运行该脚本。
我正在拼命寻找更安全,更好的方法来运行Perl脚本,我们不需要分叉父进程,或者至少不要占用所有交换空间!
规范如下:
Appserver - Weblogic 9.52
JDK - 1.5
OS - SunOS 5.10
Sun-Fire-T200
答案 0 :(得分:1)
我曾经有过几次类似的事情。由于子进程是一个分支(非常大的父进程,它可以看到所有它共享所有内存(使用写入时的副本)。我发现内核需要能够确保它可以复制所有的分叉之前的内存页面,在32位操作系统上,你的虚拟头运行速度非常快。
可能的解决方案:
答案 1 :(得分:1)
创建一个perl-server,它通过网络读取perl脚本并逐个执行。
答案 2 :(得分:0)
如果您希望保持代码不变并且有足够的磁盘可用空间,则可以在操作系统中添加足够大的交换区域。
假设您需要10 GB,以下是使用UFS的方法:
mkfile 10g /export/home/10g-swap
swap -a /export/home/10g-swap
echo "/export/home/10g-swap - - swap - no -" >> /etc/vfstab
如果您使用ZFS,那将是:
zfs create -V 10gb rpool/swap1
swap -a /dev/zvol/dsk/rpool/swap1
不要担心大量交换,这不会对性能产生任何影响,因为交换只会用于虚拟内存预留,而不是分页。
否则,正如之前的回复中已经建议的那样,避免您遇到的虚拟内存问题的一种方法是使用帮助程序,即通过网络套接字(或更高级别协议,如ssh)联系的小型服务并且“远程”执行perl脚本。
请注意,该问题与32位或64位JVM无关,只是Solaris不会过度使用内存,这是设计使然。