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

Sur mon système, Je ne peux pas exécuter une simple application Java qui démarre 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)

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

Echo 0 > / proc / sys/vm / overcommit_memory

Jusqu'-les votes pour qui est capable d'expliquer :)

Supplémentaires informations, sortie supérieure:

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

Informations supplémentaires, sortie libre:

[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
66
demandé sur Andrew Thompson 2009-07-14 15:20:00

10 réponses

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

Je soupçonne que UnixProcess effectue un fork() et qu'il n'obtient tout simplement pas assez de mémoire du système d'exploitation (si la mémoire sert, il va fork() dupliquer le processus, puis {[4] } pour exécuter le ls dans le nouveau processus de mémoire, et il ne va pas aussi loin que cela)

Modifier: Re. votre solution de surcommission, elle permet la surcommission de la mémoire système, permettant éventuellement aux processus d'allouer (mais pas utilisez) plus de mémoire que ce qui est réellement disponible. Donc, je suppose que le fork() duplique la mémoire du processus Java comme discuté dans les commentaires ci-dessous. Bien sûr, vous n'utilisez pas la mémoire puisque le ' ls ' remplace le processus Java en double.

18
répondu Brian Agnew 2009-07-14 11:41:09

C'est la solution, mais vous devez préciser:

echo 1 > /proc/sys/vm/overcommit_memory
35
répondu Michael 2013-11-06 09:26:57

Ceci est résolu dans la version Java 1.6.0_23 et vers le haut.

Voir plus de détails à http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7034935

9
répondu Alf Høgemark 2012-02-03 10:58:28

Runtime.getRuntime().exec alloue le processus avec la même quantité de mémoire que le principal. Si vous avez défini le tas sur 1 Go et essayez d'exec, il allouera un autre 1 Go pour que ce processus s'exécute.

9
répondu Attila Bukta 2013-11-06 09:27:13

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. L'utilisation d'une astuce spawn () au lieu de la fourchette simple()/exec() est conseillée.

8
répondu akarnokd 2009-07-14 11:50:36

J'ai résolu cela en utilisant 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");
    }
}
8
répondu kongo09 2011-09-20 21:47:12

Si vous regardez dans la source de java.lang.Runtime, vous verrez exec enfin appeler la méthode protégée: execVM, ce qui signifie qu'il utilise la mémoire virtuelle. Ainsi, pour un système de type Unix, la machine virtuelle dépend de la quantité d'espace d'échange + d'un certain ratio de mémoire physique.

La réponse de Michael a résolu votre problème mais elle pourrait (ou pour dire, finirait par) provoquer L'impasse O. S. dans le problème d'allocation de mémoire puisque 1 dire O. S. moins prudent de l'allocation de mémoire et 0 est juste deviner et évidemment que vous avez de la chance que O. s. je suppose que vous pouvez avoir de la mémoire cette fois. La prochaine fois? Hum.....

Une meilleure approche est que vous expérimentez votre cas et donnez un bon espace d'échange et donnez un meilleur ratio de mémoire physique utilisée et définissez la valeur sur 2 plutôt que 1 ou 0.

5
répondu Scott Chu 2010-08-01 20:51:51

Overcommit_memory

Contrôle la surcommission de la mémoire système, permettant éventuellement aux processus d'allouer (mais pas d'utiliser) plus de mémoire que ce qui est réellement disponible.

0-gestion heuristique des surcommissions. Les surcommissions évidentes de l'espace d'adressage sont refusées. Utilisé pour un système typique. Il assure une allocation sérieusement sauvage échoue tout en permettant overcommit pour réduire l'utilisation de swap. root est autorisé à allouer légèrement plus de mémoire dans ce mode. C'est la valeur par défaut.

1-Toujours overcommit. Pour certaines applications scientifiques.

2-Ne pas surcharger. L'espace d'adressage total de validation pour le système n'est pas autorisé à dépasser swap plus un pourcentage configurable (par défaut est 50) de RAM physique. Selon le pourcentage que vous utilisez, dans la plupart des situations, cela signifie qu'un processus ne sera pas tué en essayant d'utiliser la mémoire déjà allouée, mais recevra des erreurs sur l'allocation de mémoire, le cas échéant.

4
répondu ricardofunke 2011-02-21 15:44:38

Vous pouvez utiliser le wrapper Tanuki pour générer un processus avec POSIX spawn au lieu de fork. http://wrapper.tanukisoftware.com/doc/english/child-exec.html

Le WrapperManager.la fonction exec() est une alternative à Java-Runtime.exec() qui a l'inconvénient d'utiliser la méthode fork (), qui peut devenir sur certaines plates-formes très coûteuse en mémoire pour créer un nouveau processus.

4
répondu Dan Fabulich 2011-08-10 18:45:59

Aussi étrange que cela puisse paraître, un travail consiste à réduire la quantité de mémoire allouée à la JVM. Puisque fork() duplique le processus et sa mémoire, si votre processus JVM n'a pas vraiment besoin de autant de mémoire que celle allouée via-Xmx, l'allocation de mémoire à git fonctionnera.

Bien sûr, vous pouvez essayer d'autres solutions mentionnées ici (comme la sur-Validation ou la mise à niveau vers une JVM qui a le correctif). Vous pouvez essayer de réduire la mémoire si vous êtes désespéré pour une solution qui garde tout logiciel intact sans impact sur l'environnement. Gardez également à l'esprit que reducing-Xmx agressivement peut causer des OOMs. Je recommande la mise à niveau du JDK en tant que solution stable à long terme.

4
répondu Deepak Bala 2012-09-19 13:01:40