swap out of memory - java

I am working on java application and I have set the following configurations in the VM option
-Xms and -Xmx options are set to 1024m
-XX:MaxPermSize=128m Hardware :32 bit Windows 7 system with 2GB ram.
I often encounter with java out of swap space error. What could be the reason? Please help me.

The reason is that your operating system is not configured with enough swap space for the job mix that you are running. Swap space is an area on disc where the operating system puts copies memory pages when there are more virtual memory pages than physical memory pages.
So what has happened is that your JVM has asked for more virtual memory than the operating system can give it.
(Updated to include Peter's comments)
Some possible fixes:
Add more physical memory assuming that the hardware and OS allow this. (In this case, the answer the OS should allow it ...)
Configure the system with more swap space.
Kill some of the other non-essential applications and services running on the machine.
Change the Java application's JVM options to reduce the heap size.

The Java release notes under "Hotspot VM" say about this exact error;
If you see this symptom, consider increasing the available swap space
by allocating more of your disk for virtual memory and/or by limiting
the number of applications you run simultaneously. You can also
decrease your usage of memory by reducing the value of the -Xmx flag,
which limits the size of the Java object heap.
In other words, your machine is doing too many other things using up memory to be able to supply the 1GB you're telling the Java VM that it should be able to use.

Related

Process RAM usage

Just a question that i wasn't able to find an answer too after a lot of searching.
Can a single instance of a java software use more than 10GB of ram on a server that has more than 128GB of RAM installed and still run fine without any issues? Or are there any limits on memory usage of a single instance of process.
The maximum heap size for the Java Virtual Machine will most likely be constrained by your OS. Theoretically, if you have a 64-bit machine, you can allocate the JVM a heap size of 2^64. Since you have 128GB of memory, this is most likely your upper limit. Although, without knowing what your OS is, other constraints may arise.
edit: this link contains a guide to helping you setup your memory limits for your JVM on some different operating systems -> Guide

Finding Memory Requirements of Java Application

We have a desktop Java Swing application. For shipping it, we need to specify the minimum memory requirements for deploying this application. In the JVM parameters we specify 2GB as max heap size.
Is there any tool for a Windows based machine which can quantify the requirements?
Also, as follow-up question, I would like to know: If we do not specify the max heap size in Java 7, does the JVM still automatically adjust the heap size on the fly before throwing an OutOfMemoryError?
Possible approach:
If you specify your own product to work with at max. 2GB of heap, you also have to consider the other parts of memory, allocated within the Java virtual machine:
To find out your memory consumption, I suggest you to test your application with MemoryMXBean. This includes methods such as getHeapMemoryUsage() and getNonHeapMemoryUsage().
Then stress-test your applications and periodically check these properties. This way you should get a feeling for how much memory your application consumes.
Additionally to that, Windows specifies 2GB as minimum RAM for Windows 10.
So, your final minimum requirements should be Minimum = MaximumHeap (2GB) + StressTestNonHeap (?) + WindowsMinimum (2GB) + SomeSecurityThreshold (~1GB).
Further approaches:
You could also use VisualVM to check your memory consumption.
Another possibility is to use Java HotSpot Native Memory Tracking (NMT), for which I posted an example on Stack Overflow.
Anything that also informs you about non-heap memory useage is applicable.
Max heap limits:
Regarding your question
Also on another note just wanted to know if we do not specify the max heap limits with Java 7, does the JVM automatically allocates heap on the fly to adjust before throwing out of memory.
If you do not specify the max heap size, the JVM will set it automatically depending on the used GC (in Java 7 this should be UseParallelOldGC) and your system. To test this, run java -XX:+PrintVMOptions -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version and check what values are set for MaxHeapSize and UseParallelOldGC.
GC considerations:
Also: You probably want to consider using the garbage first (G1) GC, which will be the default GC in Java 9. In this question I show that the G1 GC also re-shrinks the heap if it thinks it is pratical. This may be useful if your application has memory-intensive and non-memory-intensive parts. This way, the heap may shrink during the non-memory-intensive parts, which most probably won't happen with the ParallelOldGC.
When you run the JVM without the maximum heap size for the server JVM it uses 1/4 of main memory up to 32 GB. If you use the 32-bit windows client VM, it uses 64MB or 128MB.
The best way to determine the required memory consumption is to test you application with different memory sizes. The minimum memory is the lowest memory size you are willing to support. Only you know what you are comfortable supporting.

How Much Memory Can I Allocate?

If I have 16 GB of RAM on my machine, how much can I allocate to a java command line program I'm executing? I assume java -Xmx 16g... will crash my system?
EDIT:
In light of the comments, I tried java -Xmx16g..., and it did not crash my machine. The program still ran out of memory. I tried java -Xmx32g..., which did crash my machine.
From the comments below (which have been really enlightening), I guess I just need to keep playing around with the allocations.
The size the heap memory of the virtual machine is controlled by the options - Xms
and - Xmx .
The first specifies the initial heap size and the second maximum size.
The allocation is done within the JVM itself ,and not on the OS. As more memory is needed, the JVM allocates a block of memory until the Xmx is reached.
If you need more than that, an OutOfMemoryError is thrown.
It is common to use the same value for Xms and Xmx,
causing the VM to allocate memory in the operating system only at the beginning of an execution,
not depending on the OS specific behavior.
In your case, since you set 32g as your Xmx and your system crashed, it seems you don't have this memory (swap + memory ram)
If you manually change the virtual memory size of your system, the configuration will work.
It is not possible for your OS to allocate more than 16GB and therefore your system crash. Apart from XMX and XMS that is stated in another answer there is also an -XX:+AggressiveHeap option which inspects the machine resources (size of memory and number of processors) and attempts to set various parameters to be optimal for long-running, memory allocation-intensive jobs

application terminates on heapsize

I have defined -Xmsx 1.3GB in the java VM parameters and my Eclipse does not allow more than this, when running the application I got the below exception:
Exception in thread "Thread-3" java.lang.OutOfMemoryError: Java heap space
What can I do?
You can set the maximum memory eclipse uses with -mx1300m or the like. This limitation will be because you are running 32-bit java on Windows. On a 64-bit OS, you won't have this problem.
However, its the maximum memory size you set for each application in eclipse which matters. What have you set in your run options in eclipse?
Your question is very unclear:
Are you running the application in a new JVM?
Did you set the -Xmx / -Xms parameters in the launcher for the child JVM?
If the answer to either of those questions is "no", then try doing ... both. (In particular, if you don't set at least -Xmx for the child JVM, you'll get the default heap size which is relatively small.)
If the answer to both of those questions is "yes", then the problem is that you are running into the limits of your hardware and/or operating system configuration:
On a typical 32bit Windows, a user process can only address a total 2**31 bytes of virtual memory, and some of that will be used by the JVM binaries, native libraries and various non-heap memory allocations. (On a 32 bit Linux, I believe you can have up to 2**31 + 2**30). The "fix" for this is to use a 64bit OS and a 64bit JVM.
In addition, a JVM is limited on the amount of memory that it can request by the resources of the OS'es virtual memory subsystem. This is typically bounded by the sum of the available RAM and the size of the disc files / partitions used for paging. The "fix" for this is to increase the size of the paging file / partition. Adding more RAM would probably be a good idea too.
You may want to look at the aggressive Heap option http://java.sun.com/docs/hotspot/gc1.4.2/#4.2.2.%20AggressiveHeap|outline
It solved a similiar issue for me.

How to calculate (and specify) the total memory space allowed for java process?

I have a system which cannot provide more than 1.5 Gb for Java process. Thus i need an exact way to specify java process settings, including all memory kinds inside java and possible fork.
One specific java process and system to illustrate my problem:
My current environment is java 1.6.0_18 under Ubuntu Linux 9.10.
I start large java server process with following JVM Options:
"-Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m"
Now, "top" command reports that the process uses 1.6gb memory...
Questions:
1 - how the maximal space used by java process is calculated? Please provide exact formula if possible.
( Smth. Like: max.heap + max.perm + stack + jvm space = maximal space )
2 - what is the infamous fork behavior under linux in my case? Will the forked JVM occupy extra 1.6 gb (resulting in total 3.2 Gb of used memory)?
3 - Which options must be used to absolutely ensure that no more than 1.5gb is used at any time?
thank you
#rancidfishbreath: "ulimit" will ensure that java cannot take more than specified amount of memory. My purpose is to ensure that java doesn't ever try to do that.
top reports 1.6GB because PermSize is ON TOP of the heap-size maximum heap size. In your case you set MaxPermSize to 512m and Xmx to 1024m. This amounts to 1536m. Just like in other languages, an absolutely precise number can not be calculated unless you know precisely how many threads are started, how many file handles are used, etc. The stack size per thread depends on the OS and JDK version, in your case its 1024k (if it is a 64bit machine). So if you have 10 threads you use 10240k extra as the stack is not allocated from the heap (Xmx). Most applications that behave nicely work perfectly when setting a lower stack and MaxPermSize. Try to set the ThreadStackSize to 128k and if you get a StackOverflowError (i.e. if you do lots of deep recursions) you can increase it in small steps until the problem disappears.
So my answer is essentially that you can not control it down to the MB how much the Java process will use, but you come fairly close by setting i.e. -Xmx1024m -XX:MaxPermSize=384m and -XX:ThreadStackSize=128k -XX:+UseCompressedOops. Even if you have lots of threads you will still have plenty of headroom until you reach 1.5GB. The UseCompressedOops tells the VM to use narrow pointers even when running on a 64bit JVM, thus saving some memory.
At high level JVM address space is divided in three main parts:
kernel space: ~1GB, also depends on platform, windows its more than 1GB
Java Heap: Java heap specified by user using the -Xmx, -XX:MaxPermSize, etc...
Rest of virtual address space goes to native usage of JVM, to accomodate the malloc/calloc done by JVM, native threads stack: thread respective the java threads and addition JVM native threads for GC, etc...
So you have (4GB - kernel space 1-1.25GB) ~2.75GB to play with,so you can set your java/native heap accordingly. But generally we should keep atleast 500MB for JVM native heap else there is a chances that you get native OOM. So we need to do a trade off here based on your application's java heap utilization.

Categories

Resources