66 votes

Comment résoudre "java.io.IOException: error = 12, impossible d'allouer de la mémoire" en appelant Runtime # exec ()?

Sur mon système, je ne peux pas exécuter une application Java simple que le début d'un processus. Je ne sais pas comment le résoudre.

Pourriez-vous me donner quelques conseils sur la façon de résoudre?

Le programme est:

[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");
    }

}

Le résultat est:

[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

Configuration du système:

[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)

EDIT: Solution Cela résout mon problème, je ne sais pas exactement pourquoi:

echo 0 > /proc/sys/vm/overcommit_memory

-Votes pour qui est capable d'expliquer :)

Plus d'informations, top de sortie:

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

Plus d'informations, gratuit sortie:

[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

36voto

Michael Points 249

C'est la solution mais vous devez définir:

 echo 1 > /proc/sys/vm/overcommit_memory
 

19voto

Brian Agnew Points 143181

Quel est le profil de la mémoire de votre machine ? par exemple, si vous exécutez top, de combien de mémoire libre avez-vous ?

Je soupçonne UnixProcess effectue une fork() et il n'est tout simplement pas obtenir assez de mémoire à partir de l'OS (si ma mémoire est bonne, c' fork() de dupliquer le processus, puis exec() pour exécuter la commande ls dans le nouveau processus de la mémoire, et il n'est pas aussi loin que ça)

EDIT: Ré. votre surcharge de solution, il permet overcommitting de la mémoire système, ce qui permet éventuellement de processus d'allouer (mais ne pas les utiliser) plus de mémoire que ce qui est réellement disponible. Donc je suppose que l' fork() duplique le processus Java mémoire tel que discuté dans les commentaires ci-dessous. Bien sûr, vous n'utilisez pas la mémoire depuis l' 'ls' remplace le double processus Java.

9voto

Attila Bukta Points 81

Runtime.getRuntime().exec alloue le processus avec la même quantité de mémoire que le principal. Si vous avez défini heap sur 1 Go et que vous essayez d'exécuter, il allouera 1 Go supplémentaire pour l'exécution de ce processus.

8voto

kd304 Points 8369

Je suis tombé sur ces liens:

http://mail.openjdk.java.net/pipermail/core-libs-dev/2009-May/001689.html

http://www.nabble.com/Review-request-for-5049299-td23667680.html

Semble être un bug. Il est conseillé d’utiliser une astuce spawn () au lieu d’un simple fork () / exec ().

8voto

kongo09 Points 901

J'ai résolu ceci en utilisant la 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");
    }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X