Por que limitar minha memória virtual a 512MB com ulimit -v falha a JVM?

5

Estou tentando impor o máximo de memória que um programa pode consumir em um sistema Unix. Eu pensei que ulimit -v deveria fazer o truque. Aqui está um exemplo de programa Java que escrevi para teste:

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

Por padrão, minhas configurações de ulimit são (saída 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

Quando executo meu programa java (java EatMem), ele é executado sem problemas. Agora eu tento limitar a memória máxima disponível para qualquer programa lançado no shell atual para 512MB, iniciando o seguinte comando:

ulimit -v 524288

ulimit -a output mostra o limite a ser configurado corretamente (suponho):

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

Se eu agora tentar executar meu programa java, isso me dá o seguinte erro:

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

O ideal é que isso não aconteça, já que meu programa Java ocupa apenas 128 MB de memória, o que está bem dentro dos parâmetros ulimit especificados. Se eu mudar os argumentos para o meu programa Java como abaixo:

java -Xmx256m EatMem

O programa funciona novamente bem. Ao tentar dar mais memória do que limitado por ulimit como:

java -Xmx800m EatMem

resulta em erro esperado. Por que o programa falha ao executar no primeiro caso depois de configurar o ulimit?

Eu tentei o teste acima no Ubuntu 11.10 e 12.0.4 com Java 1.6 e Java 7

    
por Narinder Kumar 10.09.2012 / 12:32

1 resposta

3

ulimit -v define o espaço de endereço máximo que um programa pode usar. Isso inclui toda a memória compartilhada, como bibliotecas, espaço de pilha de encadeamentos, memória direta, etc. Como a JVM não foi projetada para rodar em um ambiente limitado de memória virtual como este, ela pode não se posicionar de maneira ideal. isto é porque a memória virtual é normalmente muito, muito barata. Eu suspeito que você tenha que definir este valor muito mais alto para obter a execução da JVM.

BTW: A JVM aloca o tamanho máximo de heap na inicialização.

Se eu definir ulimit -v 524288 e tentar fazer

Executa ok

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

falha com falha no malloc

java -mx300m -version

Ocorreu um erro durante a inicialização da VM

java -mx400m -version
java -mx512m -version

Esse é mais ou menos o comportamento esperado.

    
por 10.09.2012 / 12:37