3

We have a Java-based app (TeamCity, on Tomcat, on Java 1.7) running on Windows (Server 2012 R2). Java runs with a 6GB max heap size, and the system has 10GB of RAM. It is the only non-OS service running on the machine.

For steady state, everything is fine. Unfortunately, when Java occasionally does a full GC, we find that part of the Java heap has been paged out, needs to be paged back in, and therefore the GC takes several minutes instead of less-than-to-a-few seconds.

General wisdom is never to disable the Windows pagefile entirely, but I wonder if this is a counter-example? (We really don't want the world to pause for minutes while it pages it back in for a GC!)

Is there a better way of ensuring the JVM never gets paged to disk, in light of a high-IO workload causing Windows to evict some of the heap in favour of disk cache?

Thanks, Rob

1 Answer 1

3

Ugh, Java. :(

First I'll give you the short answer: Yes, I think this could be a valid reason to run without a page file, knowing of course that you'll no longer be able to generate system crash dumps, and your machine will crash or destabilize to the point where you wish it would have crashed if you run out of memory. However, you just have to weigh the pros versus the cons for yourself. Technically, Windows can run fine without a page file as long as you don't run it out of memory... barring old or poorly-designed applications that stupidly assume the existence of a pagefile, for example.

Now, the long answer.

First, why does paging happen? The operating system uses a page replacement algorithm, where every memory page is marked with an "age," which is a counter since the last time that memory page was accessed. Memory pages that haven't been accessed in a long time are eventually written out to disk, so that other potentially more important data can be given space in RAM. If a process actively uses its allocated memory more often, there is less of a chance of those pages being written out to the page file.

Application developers can call the VirtualLock Windows API function to ask Windows to lock pages into the working set of the calling process. It requires a certain operating system privilege to be able to successfully call that function however, since having the ability to lock pages into RAM could potentially have adverse effects on the entire system if you don't play nice. But this doesn't help you, because VirtualLock is something you would use in your code while you were developing an application. It's not something you can call on someone else's running process.

But with Java, now you are running a virtual machine with its own internal memory manager on top of the actual operating system and its memory manager, and those two don't always work well together, as you are experiencing. Locking a process (or more accurately, locking all of the memory allocated by a process) into physical memory is operating system-specific, and as such, is not something that would be handled by Java, since Java strives to be agnostic and cross-platform.

So, the only way I know of to get Java to lock its allocations into RAM so that they don't get paged out, is to use JNI (Java Native Interface) and mlock()/mlockall().

3
  • Yes, I suspected it was an "Ugh, Java", potentially in combination with "Ugh, Windows" :-). Thanks for the reassurance I'm not missing anything obvious.
    – rmc47
    Jan 28, 2015 at 18:50
  • Np, but don't blame Windows... the same advice about using JNI to lock memory applies to *nix as well. :)
    – Ryan Ries
    Jan 28, 2015 at 19:53
  • Indeed, though Linux has the ability to control how aggressively stuff gets swapped out (en.wikipedia.org/wiki/Swappiness), which allows more control than Windows when the app doesn't allow it.
    – rmc47
    Jan 28, 2015 at 21:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .