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