2

I was posting an answer to this question, and I realized that I'm confused over something. I asked a few co-workers comfortable in Java and we're all a little stumped.

What happens in this scenario:

  1. Start JVM with start-up size of 512MB and maximum size of 2GB.
  2. Your underlying OS has 1GB of memory left, so the JVM is allowed to start up.
  3. Your program uses over 1GB of memory.

At this point, you've used all available JVM memory, but you haven't breached the JVM memory limit you set up on launch. The OS is constraining your ability to get more resources, not the JVM itself.

I would have thought that this would result in an OutOfMemoryError, as you would get if you overran the 2GB JVM size limit. I have to admit though, in practice when we're running too many processes on our servers, I tend to see a slow-down and no memory exceptions.

Please note that I'm aware of paging and that processes get killed off in Linux when memory is exhausted. I was interested in knowing if any additional mechanisms are in place at the JVM level that could cause more of a blocking effect since that's what the person in the other question was asking in his comment. I realize that the answer may simply be "No, there are no additional mechanisms in place."

Follow-Up Questions/Comments

Is this because memory exceptions are not thrown unless you hit the actual JVM memory limit? If so, what happens when the OS cannot give the JVM more memory when it hasn't reached its limit? Is there some kind of blocking or a similar mechanism until memory is available in the OS?

Community
  • 1
  • 1
John Humphreys
  • 37,047
  • 37
  • 155
  • 255
  • Well, there is demand paging for one, and also swap space; if you exhaust the OS memory completely, you don't see OOMs, the OS simply terminates your process -- or another one :p – fge Mar 11 '14 at 14:09
  • Yeah, I'm aware of paging and that processes get killed off in Linux when memory is exhausted. I was interested in knowing if any additional mechanisms are in place at the JVM level that could cause more of a blocking effect since that's what the person in the other question was asking in his comment. – John Humphreys Mar 11 '14 at 14:17
  • Well, the maximum per-thread stack size can be limited, yes; but in this case you will get a `StackOverflowError`, not an `OutOfMemoryError`... Except if OS resources themselves are exhausted. – fge Mar 11 '14 at 14:20

1 Answers1

5

All modern operating systems use page caching, where data is swapped between memory and disk. While it's a slight oversimplification, each process constrained by the number of addresses available (typically 232 or 264), not the amount of physical memory.

One of the reasons your server starts to run slowly under load is because it's having to swap data more frequently, which involves comparatively slow disk reads.

From the JavaDoc for OutOfMemoryError:

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

What happens from an operating system perspective should a process exceed the memory limits, is specific to a particular operating system, but typically the process is terminated.

Nick Holt
  • 33,455
  • 4
  • 52
  • 58