在我的系统上,我无法运行启动进程的简单Java应用程序。我不知道该怎么解决。
你能给我一些如何解决的提示吗?
该计划是:
[root@newton sisma-acquirer]# cat prova.java
import java.io.IOException;
public class prova {
public static void main(String[] args) throws IOException {
Runtime.getRuntime().exec("ls");
}
}
结果是:
[root@newton sisma-acquirer]# javac prova.java && java -cp . prova
Exception in thread "main" java.io.IOException: Cannot run program "ls": java.io.IOException: error=12, Cannot allocate memory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:474)
at java.lang.Runtime.exec(Runtime.java:610)
at java.lang.Runtime.exec(Runtime.java:448)
at java.lang.Runtime.exec(Runtime.java:345)
at prova.main(prova.java:6)
Caused by: java.io.IOException: java.io.IOException: error=12, Cannot allocate memory
at java.lang.UNIXProcess.<init>(UNIXProcess.java:164)
at java.lang.ProcessImpl.start(ProcessImpl.java:81)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:467)
... 4 more
系统配置:
[root@newton sisma-acquirer]# java -version
java version "1.6.0_0"
OpenJDK Runtime Environment (IcedTea6 1.5) (fedora-18.b16.fc10-i386)
OpenJDK Client VM (build 14.0-b15, mixed mode)
[root@newton sisma-acquirer]# cat /etc/fedora-release
Fedora release 10 (Cambridge)
编辑:解决方案 这解决了我的问题,我不确切知道原因:
echo 0&gt;的/ proc / SYS / VM / overcommit_memory
为谁能够解释的向上投票:)
其他信息,最高输出:
top - 13:35:38 up 40 min, 2 users, load average: 0.43, 0.19, 0.12
Tasks: 129 total, 1 running, 128 sleeping, 0 stopped, 0 zombie
Cpu(s): 1.5%us, 0.5%sy, 0.0%ni, 94.8%id, 3.2%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1033456k total, 587672k used, 445784k free, 51672k buffers
Swap: 2031608k total, 0k used, 2031608k free, 188108k cached
其他信息,免费输出:
[root@newton sisma-acquirer]# free
total used free shared buffers cached
Mem: 1033456 588548 444908 0 51704 188292
-/+ buffers/cache: 348552 684904
Swap: 2031608 0 2031608
答案 0 :(得分:35)
这是解决方案,但您必须设置:
echo 1 > /proc/sys/vm/overcommit_memory
答案 1 :(得分:18)
您机器的内存配置文件是什么?例如如果你运行top
,你有多少可用内存?
我怀疑UnixProcess
执行fork()
并且它根本没有从操作系统获得足够的内存(如果内存服务,它将fork()
复制进程然后{{1}在新的内存进程中运行ls,并没有达到那个程度)
编辑:Re。你的overcommit解决方案,它允许过度使用系统内存,可能允许进程分配(但不使用)比实际可用内存更多的内存。所以我想exec()
重复了Java进程内存,如下面的评论所述。当然你不使用内存,因为'ls'取代了重复的Java进程。
答案 2 :(得分:9)
Runtime.getRuntime().exec
使用与main相同的内存量分配进程。如果您将堆设置为1GB并尝试执行,那么它将为该进程分配另外1GB来运行。
答案 3 :(得分:9)
这是在Java版本1.6.0_23及更高版本中解决的。
上查看更多详情答案 4 :(得分:8)
我遇到了这些链接:
http://mail.openjdk.java.net/pipermail/core-libs-dev/2009-May/001689.html
http://www.nabble.com/Review-request-for-5049299-td23667680.html
似乎是一个错误。建议使用spawn()技巧而不是普通的fork()/ exec()。
答案 5 :(得分:8)
我使用JNA解决了这个问题:https://github.com/twall/jna
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public class prova {
private interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);
int system(String cmd);
}
private static int exec(String command) {
return CLibrary.INSTANCE.system(command);
}
public static void main(String[] args) {
exec("ls");
}
}
答案 6 :(得分:5)
如果你查看java.lang.Runtime的源代码,你会看到exec最后调用protected method:execVM,这意味着它使用了虚拟内存。因此,对于类Unix系统,VM取决于交换空间量+某些物理内存比率。
迈克尔的答案确实解决了你的问题,但它可能(或者说,最终会)导致O.S.内存分配问题中的死锁问题从1开始就告诉O.S.不太注意内存分配和0只是猜测&amp;显然你很幸运,O.S。猜猜你现在可以有记忆了。下次?嗯.....更好的方法是你试验你的案例&amp;提供良好的交换空间&amp;提供更好的物理内存比率和将值设置为2而不是1或0。
答案 7 :(得分:4)
overcommit_memory
控制系统内存的过度使用,可能允许进程分配(但不使用)比实际可用内存更多的内存。
0 - 启发式过度使用处理。地址空间的明显过度使用被拒绝。用于典型系统。它确保严重的疯狂分配失败,同时允许过度使用以减少交换使用。 root允许在这种模式下分配更多的内存。这是默认值。
1 - 总是过度使用。适合某些科学应用。
2 - 不要过度使用。系统的总地址空间提交不允许超过交换加上物理RAM的可配置百分比(默认值为50)。根据您使用的百分比,在大多数情况下,这意味着在尝试使用已分配的内存时不会终止进程,但会在内存分配时收到相应的错误。
答案 8 :(得分:4)
您可以使用Tanuki包装器生成POSIX spawn而不是fork的进程。 http://wrapper.tanukisoftware.com/doc/english/child-exec.html
WrapperManager.exec()函数是Java-Runtime.exec()的替代方法,它缺点是使用fork()方法,在某些平台上创建新进程的内存非常昂贵。
答案 9 :(得分:4)
听起来很奇怪,一个解决方法是减少分配给JVM的内存量。由于fork()复制了进程及其内存,如果你的JVM进程并不真正需要通过-Xmx分配的内存,那么git的内存分配就可以了。
当然,您可以尝试此处提到的其他解决方案(例如过度提交或升级到具有此修复程序的JVM)。如果您急需一个能够保持所有软件完整且不受环境影响的解决方案,您可以尝试减少内存。还要记住,减少-Xmx会积极地导致OOM。我建议将JDK升级为长期稳定的解决方案。