Runtime # exec ()를 호출하여“java.io.IOException : error = 12, Cannot allocate memory”를 해결하는 방법은 무엇입니까?
내 시스템에서 프로세스를 시작하는 간단한 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)
편집 : 솔루션 이것은 내 문제를 해결합니다. 이유를 정확히 모르겠습니다.
에코 0> / 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
컴퓨터의 메모리 프로필은 무엇입니까? 예를 들어 실행하면 사용 top
가능한 메모리가 얼마나됩니까?
나는 UnixProcess
a를 수행하고 fork()
단순히 OS에서 충분한 메모리를 얻지 못하는 것으로 의심 됩니다 (메모리 가 작동하는 fork()
경우 프로세스를 복제 한 다음 exec()
새 메모리 프로세스에서 ls를 실행하고 그만큼 멀리 가지 않습니다)
편집 : Re. 오버 커밋 솔루션은 시스템 메모리의 오버 커밋을 허용하여 프로세스가 실제로 사용 가능한 것보다 더 많은 메모리를 할당 (사용하지 않음) 할 수 있도록합니다. 그래서 나는 fork()
아래 주석에서 논의 된 것처럼 Java 프로세스 메모리를 복제 한다고 생각 합니다. 물론 'ls'가 중복 Java 프로세스를 대체하기 때문에 메모리를 사용하지 않습니다.
이것이 해결책이지만 다음을 설정해야합니다.
echo 1 > /proc/sys/vm/overcommit_memory
이것은 Java 버전 1.6.0_23 이상에서 해결되었습니다.
See more details at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7034935
Runtime.getRuntime().exec
allocates the process with the same amount of memory as the main. If you had you heap set to 1GB and try to exec then it will allocate another 1GB for that process to run.
I came across these links:
http://mail.openjdk.java.net/pipermail/core-libs-dev/2009-May/001689.html
http://www.nabble.com/Review-request-for-5049299-td23667680.html
Seems to be a bug. Usage of a spawn() trick instead of the plain fork()/exec() is advised.
I solved this using 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");
}
}
If you look into the source of java.lang.Runtime, you'll see exec finally call protected method: execVM, which means it uses Virtual memory. So for Unix-like system, VM depends on amount of swap space + some ratio of physical memory.
Michael's answer did solve your problem but it might (or to say, would eventually) cause the O.S. deadlock in memory allocation issue since 1 tell O.S. less careful of memory allocation & 0 is just guessing & obviously that you are lucky that O.S. guess you can have memory THIS TIME. Next time? Hmm.....
Better approach is that you experiment your case & give a good swap space & give a better ratio of physical memory used & set value to 2 rather than 1 or 0.
overcommit_memory
Controls overcommit of system memory, possibly allowing processes to allocate (but not use) more memory than is actually available.
0 - Heuristic overcommit handling. Obvious overcommits of address space are refused. Used for a typical system. It ensures a seriously wild allocation fails while allowing overcommit to reduce swap usage. root is allowed to allocate slighly more memory in this mode. This is the default.
1 - Always overcommit. Appropriate for some scientific applications.
2 - Don't overcommit. The total address space commit for the system is not permitted to exceed swap plus a configurable percentage (default is 50) of physical RAM. Depending on the percentage you use, in most situations this means a process will not be killed while attempting to use already-allocated memory but will receive errors on memory allocation as appropriate.
You can use the Tanuki wrapper to spawn a process with POSIX spawn instead of fork. http://wrapper.tanukisoftware.com/doc/english/child-exec.html
The WrapperManager.exec() function is an alternative to the Java-Runtime.exec() which has the disadvantage to use the fork() method, which can become on some platforms very memory expensive to create a new process.
As weird as this may sound, one work around is to reduce the amount of memory allocated to the JVM. Since fork() duplicates the process and its memory, if your JVM process does not really need as much memory as is allocated via -Xmx, the memory allocation to git will work.
Of course you can try other solutions mentioned here (like over-committing or upgrading to a JVM that has the fix). You can try reducing the memory if you are desperate for a solution that keeps all software intact with no environment impact. Also keep in mind that reducing -Xmx aggressively can cause OOMs. I'd recommend upgrading the JDK as a long-term stable solution.
'IT박스' 카테고리의 다른 글
pip 제거를위한 확인 프롬프트 무시 (0) | 2020.11.16 |
---|---|
속성의 이름이 유형과 같아야합니까? (0) | 2020.11.15 |
Scala에서 여러 유형 경계를 어떻게 설정합니까? (0) | 2020.11.15 |
테스트 구성을위한 PHPUnit 모범 사례 (0) | 2020.11.15 |
AngularJS 단위 테스트에서 $ modal 조롱 (0) | 2020.11.15 |