5 votos

¿Por qué limita mi memoria virtual a 512MB con ulimit - v crash la JVM?

Estoy tratando de hacer cumplir la máxima de memoria de un programa puede consumir en un sistema Unix. Pensé ulimit -v debe hacer el truco. Aquí se muestra un ejemplo de programa Java que he escrito para la prueba :

import java.util.*;
import java.io.*;

public class EatMem {

  public static void main(String[] args) throws IOException, InterruptedException {
    System.out.println("Starting up...");
    System.out.println("Allocating 128 MB of Memory");
    List<byte[]> list = new LinkedList<byte[]>();
    list.add(new byte[134217728]); //128 MB
    System.out.println("Done....");
  }
}

De forma predeterminada, mi ulimit ajustes (salida de ulimit-a) :

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31398
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 31398
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Cuando ejecuto mi programa java (java EatMem), se ejecuta sin problemas. Ahora trato de límite máximo de memoria disponible para cualquier programa que se lanzó en el shell actual de 512 mb por lanzar el siguiente comando :

ulimit -v 524288

ulimit-a la salida muestra el límite establecido correctamente (supongo):

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31398
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 31398
virtual memory          (kbytes, -v) 524288
file locks                      (-x) unlimited

Si yo ahora intento ejecutar mi programa java, me da el siguiente error:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

Idealmente no debe ocurrir como mi programa Java es sólo tomar alrededor de 128 mb de memoria que está bien dentro de mi especificado ulimit parámetros. Si puedo cambiar los argumentos de mi programa Java de la siguiente manera:

java -Xmx256m EatMem

De nuevo el programa funciona bien. Mientras que tratando de dar más memoria de la que limita por ulimit como :

java -Xmx800m EatMem

resultados en el error esperado. ¿Por qué el programa no se ejecuta en el primer caso, después de establecer ulimit ?

He tratado de la prueba anterior en Ubuntu 11.10 y 12.0.4 con Java 1.6 y Java 7

1voto

Peter Lawrey Puntos 116

ulimit -v establece el máximo de espacio de direcciones de un programa puede utilizar. Esto incluye toda la memoria compartida, como las bibliotecas, hilo de espacio en la pila, directo a memoria etc. Como la JVM no está diseñado para ejecutarse en una memoria virtual limitada entorno como este no puede sentar a sí mismo en una forma óptima. es decir, debido a que la memoria virtual es normalmente muy, muy barato. Sospecho que tiene que establecer este valor mucho mayor para obtener la JVM para que se ejecute.

BTW: La JVM asigna el máximo tamaño de la pila en el inicio.


Si he de poner ulimit -v 524288 y el intento de hacer

Funciona bien

java -mx64m -version
java -mx128m -version
java -mx256m -version

Se bloquea con un fracaso a malloc

java -mx300m -version

Error durante la inicialización de la VM

java -mx400m -version
java -mx512m -version

Este es más o menos el comportamiento esperado.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: