Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am trying to enforce maximum memory a program can consume on a Unix system. I thought ulimit -v should do the trick. Here is a sample Java program I have written for testing :

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

By default, my ulimit settings are (output of 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

When I execute my java program (java EatMem), it executes without any problems. Now I try to limit max memory available to any program launched in the current shell to 512MB by launching the following command :

ulimit -v 524288

ulimit -a output shows the limit to be set correctly (I suppose):

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

If I now try to execute my java program, it gives me the following error:

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

Ideally it should not happen as my Java program is only taking around 128MB of memory which is well within my specified ulimit parameters. If I change the arguments to my Java program as below:

java -Xmx256m EatMem

The program again works fine. While trying to give more memory than limited by ulimit like :

java -Xmx800m EatMem

results in expected error. Why the program fails to execute in the first case after setting ulimit ?

I have tried the above test on Ubuntu 11.10 and 12.0.4 with Java 1.6 and Java 7

share|improve this question

migrated from stackoverflow.com Sep 11 '12 at 2:57

This question came from our site for professional and enthusiast programmers.

1 Answer 1

ulimit -v sets the maximum address space a program can use. This includes all shared memory like libraries, thread stack space, direct memory etc. As the JVM isn't designed to run in a limited virtual memory environment like this it may not lay itself out in an optimal way. i.e. because virtual memory is normally very, very cheap. I suspect you have to set this value much higher to get the JVM to run.

BTW: The JVM allocates the maximum heap size on startup.


If I set ulimit -v 524288 and attempt to do

Runs ok

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

Crashes with a failure to malloc

java -mx300m -version

Error occured during initialization of VM

java -mx400m -version
java -mx512m -version

This is more or less expected behaviour.

share|improve this answer
    
Can you say what they are? –  Peter Lawrey Sep 10 '12 at 11:02
    
Sorry, re-writing the phrase as accidentally hit enter last time. Thanks @peter-lawrey for the explanation. But I am still not clear about why it still works when I pass -Xmx parameter explicitly ? BTW, When I try using ulimit -m 524288, it works as per the expectations i.e. when I try allocating 128MB of memory in the program, works without any issues but anything more than 512MB gets me an error. –  Narinder Kumar Sep 10 '12 at 11:05
    
I have added what I see from using ulimit -v. It behaves about as I would expect. Its worth remembering that the maximum heap size is NOT the maximum virtual memory used. –  Peter Lawrey Sep 10 '12 at 11:19
    
So does it mean, if I have to control the maximum memory a Java program can consume, ulimit -v is not the correct approach? Is ulimit -m a better option or there is something else I should consider ? –  Narinder Kumar Sep 10 '12 at 12:05
    
This may be closer to what you need because it controls actual memory used. Using such a hard limit is dangerous because it will crash the JVM. It is better if you can set reasonable limits the JVM can monitor (either as well or instead of a hard limit) –  Peter Lawrey Sep 10 '12 at 12:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.