Multiple JVMs with sum of -xms greater than host's RAM - java

Note: I am new to Java (I am a Python dev; the idea of JVM is alien to me)
Say you have a server w/ 8-core 160GB RAM
If you run a Java program with -xms 100G, it would not throw any errors.
What if you run two or more Java programs (multiple JVMs) with -xms -100G?
If memeory permits, its it acceptable to run multiple JVMs on a same host?
Any references would be appreciated!

No (sane) OS will give you actual memory to back-up your needs, ever heard about swap space? And this is true for python too, memory management is not different, since python still operates with virtual memory, right?
If you really want your VM's memory to be back-ed up by physical memory, there is flag for that: -XX:+AlwaysPreTouch, but using it will mean that all the memory that your VM uses has to be zeroed ("touched") and that means it will be a slower start - especially true for such big amounts of memory.
-Xmx and -Xms are really just start-up flags that tell you the initial memory you want and the max memory you want (usually they have the same value), but that is still virtual memory that is being asked from the OS.

-xms defines the minimum mandatory requirement for the JVM. At the time of launching the JVM if the memory is available, it will come up without any issues.Same is true for multiple JVM launches as well.
Inshort, as long as minimum memory requirement is getting fulfilled JVM will launch successfully.
http://blog.paulgu.com/java/6-common-errors-in-setting-java-heap-size/

Related

Does JVM create its own swap?

Does JVM creates its own swap memory or it takes the OS swap memory? What if OS doesn't have any swap memory, will JVM stick to RAM only?
The JVM behaves just like any other process running on the kernel. When the JVM needs heap space, it will request memory via the malloc library call, which in turn uses a system call (brk, sbrk or mmap) to allocate space using the OS virtual memory system. Whether this involves paging to swap is not relevant to the JVM, it's just asking for space and leaves the details up to the OS VM sub-system.
From a performance perspective, it is important to bear this in mind when configuring your JVM. Although you can make the heap bigger than the physical memory of your machine it will deliver worse performance than if the heap is less than physical memory. This is a result of the paging activity that must occur once the heap exceeds physical memory.
As an aside, Azul (who I work for) have a JVM called Zing that does things slightly differently. Rather than using the Linux VM sub-system, we have our own kernel-level software (called Zing System Tools or ZST). This allows us to handle virtual memory in a way that is specific to the JVM, rather than in a general purpose way as Linux does. Memory can be returned from a JVM to ZST when not being used, cache lines can be more optimized and we also have the ability to allow a JVM to exceed the configured heap size to prevent an OOM error.
Virtual memory is a trick used by many operating systems to for all practical purposes behave like they have more physical RAM than they really have. This is usually invisible to normal programs and the operating system handles everything.
HotSpot-based Java implementations are normal programs but can grow very big. It is therefore important that the JVM is configured correctly so it does not use too much memory and cause swapping. The defaults are usually reasonable.
So, in short. The jvm does not concern itself with swapping - this is purely an operating system task.
JVM wont create its own swap memory in disk, it uses OS swap just like any other app. If OS doesnt have SWAP configured, it will stick to RAM.

How do I start a JVM with unlimited memory?

How do I start a JVM with no heap max memory restriction? So that it can take as much memory as it can ?
I searched if there is such an option, but I only seem to find the -Xmx and -Xms options.
EDIT:
Let's say I have a server with 4GB of RAM and it only runs my application. And, let's say I have another server with 32GB of RAM. I don't want to start my application with 4GB of memory limit because the second machine should be able to handle more objects
-XX:MaxRAMFraction=1 will auto-configure the max heap size to 100% of your physical ram or the limits imposed by cgroups if UseCGroupMemoryLimitForHeap is set.
OpenJDK 10 will also support a percentage based option MaxRAMPercentage allowing more fine-grained selection JDK-8186248. This is important to leave some spare capacity for non-heap data structures to avoid swapping.
You can't (or at least, I don't know a JVM implementation that supports it). The JVM needs to know at start up how much memory it can allocate, to ensure that it can reserve a contiguous range in virtual memory. This allows - among others - for simpler reasoning in memory management.
If virtual memory would be expanded at runtime, this could lead to fragmented virtual memory ranges, making tracking and referencing memory harder.
However, recent Java versions have introduced options like -XX:MaxRAMPercentage=n, which allows you to specify the percentage of memory to allocate to the Java heap, instead of an absolute in bytes. For example -XX:MaxRAMPercentage=80 will allocate 80% of the available memory to the Java heap (the default is 25%).
The -XX:MaxRAMPercentage only works for systems with more than 200MB of memory (otherwise you need to use -XX:MinRAMPercentage, default 50%).
You can also use -XX:InitialRAMPercentage to specify the initial memory allocated to Java (MaxRAMPercentage is similar to -Xmx, InitialRAMPercentage is similar to -Xms).
JVM is running on physical computer that has limited memory. Therefore JVM cannot have unlimited memory as far as the memory is limited by definition. You can however supply very huge limit in -Xmx option.
The question is however why do you need the unlimited memory and even more correct question is how much memory do you really need?
On Linux, you can use the free and awk commands to calculate an inline value like this:
JAVA_OPT_MAX_MEM=$(free -m | awk '/Mem:/ {printf "-Xmx%dm", 0.80*$2}')
Example Result (on a machine with 3950m of free memory):
JAVA_OPT_MAX_MEM=-Xmx3160m
The calculated option is 80% of the total reported memory.

How Can I change JVM Default Heap Settings

JVM Default Setting :
-Xms32m -Xmx128m -Xss128k -Xoss128k -XX:ThreadStackSize=128
I need change Default Heap settings and want to increase heap memory at 64gb server.
what problems can occur when default settings will be changed
What is the limit to increase jvm heap memory
And How Can Change these parameter of jvm
How do I change JVM default heap settings?
It depends on what you mean by the "default" settings.
If you mean the "default" settings as implemented by the java command, then you can override the default setting using the -Xmx... (etcetera) command line options as described by #BetaRide. However, you cannot change what the java commmand's defaults are / how they are calculated.
If you mean the "default" settings used by some Java-based application, then there is no general answer. Different applications specify the heap size to be used in different ways. and provide different was to change the heap size. A common mechanism is to set a $JAVA_OPTS environment variable, but that is by no means universal. Check the application documentation or read the launch script.
What problems can occur when the default settings are changed?
If you make the heap too small, you can cause the application to suffer OutOfMemoryErrors. Depending on how well the application is written, it will either error out (a good thing), go into a "death spiral", or get into an indeterminate state. (The last happens if the OOMEs happen on a worker thread and the thread dies. The solution is to add a default uncaught exception handler that specifically causes the application to exit whenever it sees an Error or Error subclass.)
If you make the heap significantly bigger than you have physical memory, then you risk making the JVM thrash virtual memory when it does a garbage collection. That leads to bad performance, and on some OSes it can lead to the OS terminating your application; e.g. see https://unix.stackexchange.com/questions/479575/why-is-the-linux-oom-killer-terminating-my-programs
An overly large heap can also lead to unresponsiveness during garbage collection ... simply because certain phases of the GC (or the entire GC) will "stop the world", and the length of the stoppage is bigger for a bigger heap. (In some Java GC's, it is just the size of the "new" space that matters. In others, it is the entire heap size that matters. Refer to the Oracle documentation on GC Ergonomics for more details ... depending on your Java version.)
What is the limit to increase JVM heap memory?
There are a number of relevant limits.
Your platform's processor architecture and OS may limit you. For instance on a 32-bit intel platform, the maximum addressible memory for a JVM process would be 2^32 bytes ... and the OS will reserve a significant amount of that for its own purposes.
The OS will typically limit aggregate virtual memory usage for all processes based on the amount of available physical memory and swap space.
Some OSes (and containers) allow the administrator (or user) to place external limits on the virtual memory used by a process or group of processes.
Independent of the above, there are the practical limits I mentioned above. (A heap that is too big can cause problems with responsiveness, virtual memory thrashing ... and the OOM killer.)
The only option you need is
java -Xmx65536m your.main.Class
To answer your questions:
It's no longer limited to the default heaps size.
See What is the largest possible heap size with a 64-bit JVM?

jvm issue at startup

I can set the max memory as 1000 and not more than that, if I set the memory more than that, it throws the following error.
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
My question is, why jvm looks for the max memory at startup?
Thanks in advance.
The Sun JVM needs a contiguous area of memory for its heap. Using the tool vmmap from the Sysinternals suite you can examine the memory layout of the Java process exactly. To do that, write a simple Java program like this:
public class MemoryLayout {
public static void main(String[] args) throws java.io.IOException {
System.in.read();
}
}
Compile that program and run it using the large heap settings
javac MemoryLayout.java
java -Xmx1000m -Xms1000m MemoryLayout
Then, start vmmap, select the java process and look for the yellow memory region whose size is larger than 1000000k. This is the JVM heap. Look further below, and you will eventually find a purple row indicating that there is a DLL file mapped. This DLL file prevents your JVM heap from growing bigger.
If you know what you are doing, you can then rebase that DLL, so it will be loaded at a different address. Microsoft provides a tool called rebase.exe as part of the Microsoft Platform SDK (I have version 5.2.3790.1830).
There are two command line parameters that directly control the size of the (normal) heap:
-Xmx<nnn> sets the maximum heap size
-Xms<nnn> sets the initial heap size
In both cases <nnn> is a number of bytes, with a k or m on the end to indicate kilobytes and megabytes respectively. The initial size gives the heap size allocated when the JVM starts, and the maximum size puts a limit on how big it can grow. (But the JVM also allocates memory for buffers, the "permgen" heap, stacks and other things ... in addition to the normal heap.)
It is not clear what options you are actually giving. (A value of 1000 doesn't make any sense. The -Xmx size has to be more than 2 megabytes and the -Xms size has to be more than 1 megabytes; see this page.)
There are advantages and disadvantages in making the initial heap size smaller than the maximum heap size; e.g. -Xms100m -Xmx1000m. But there is no point making the maximum heap size larger than the amount of virtual memory your machine can allocate to the JVM.
why jvm looks for the max memory at startup.
It wants to make sure that it can eventually allocate the maximum amount which you said it could have.
Why do you need to set a higher maximum then your machine actually supports?
Answer: It would make JVM configuration easier, if you could just set it to basically unlimited, especially if you deployed to different machines. This was possible in earlier versions, but for the current Sun JVM, you have to figure out a "proper" value for every machine. Hopefully, there will be more clever/automatic memory settings in the future.
As elaborated here for implementation reasons (basically it makes performance faster and that is their priority) the JVM requires contiguous memory addressing, so it has to establish that it has that at startup, otherwise it might to be available later.
The fact of the matter is that the JVM in many ways is a server-side oriented technology. That is where Java is popular so that is what gets the development attention.
If you use a 64-bit JVM on a 64-bit OS you won't have this problem. This is only a problem on 32-bit OSes.

Speed tradeoff of Java's -Xms and -Xmx options

Given these two commands
A:
$ java -Xms10G -Xmx10G myjavacode input.txt
B:
$ java -Xms5G -Xmx5G myjavacode input.txt
I have two questions:
Since command A reserves more memory with its parameters, will A run faster than B?
How do -Xmx and -Xms affect the running process and the output of my program?
The -Xmx argument defines the max memory size that the heap can reach for the JVM. You must know your program well and see how it performs under load and set this parameter accordingly. A low value can cause OutOfMemoryExceptions or a very poor performance if your program's heap memory is reaching the maximum heap size. If your program is running in dedicated server you can set this parameter higher because it wont affect other programs.
The -Xms argument sets the initial heap memory size for the JVM. This means that when you start your program the JVM will allocate this amount of memory instantly. This is useful if your program will consume a large amount of heap memory right from the start. This avoids the JVM to be constantly increasing the heap and can gain some performance there. If you don't know if this parameter is going to help you, don't use it.
In summary, this is a compromise that you have to decide based only in the memory behavior of your program.
It depends on the GC your java is using. Parallel GCs might work better on larger memory settings - I'm no expert on that though.
In general, if you have larger memory the less frequent it needs to be GC-ed - there is lots of room for garbage. However, when it comes to a GC, the GC has to work on more memory - which in turn might be slower.
I have found that in some cases too much memory can slow the program down.
For example I had a hibernate based transform engine that started running slowly as the load increased. It turned out that each time we got an object from the db, hibernate was checking memory for objects that would never be used again.
The solution was to evict the old objects from the session.
Stuart
Allocation always depends on your OS. If you allocate too much memory, you could end up having loaded portions into swap, which indeed is slow.
Whether your program runs slower or faster depends on the references the VM has to handle and to clean. The GC doesn't have to sweep through the allocated memory to find abandoned objects. It knows it's objects and the amount of memory they allocate by reference mapping. So sweeping just depends on the size of your objects. If your program behaves the same in both cases, the only performance impact should be on VM startup, when the VM tries to allocate memory provided by your OS and if you use the swap (which again leads to 1.)
The speed tradeoffs between various settings of -Xms and -Xmx depend on the application and system that you run your Java application on. It also depends on your JVM and other garbage collection parameters you use.
This question is 11 years old, and since then the effects of the JVM parameters on performance have become even harder to predict in advance. So you can try different values and see the effects on performance, or use a free tool like Optimizer Studio that will find the optimal JVM parameter values automatically.
It is difficult to say how the memory allocation will affect your speed. It depends on the garbage collection algorithm the JVM is using. For example if your garbage collector needs to pause to do a full collection, then if you have 10 more memory than you really need then the collector will have 10 more garbage to clean up.
If you are using java 6 you can use the jconsole (in the bin directory of the jdk) to attach to your process and watch how the collector is behaving. In general the collectors are very smart and you won't need to do any tuning, but if you have a need there are numerous options you have use to further tune the collection process.
> C:\java -X
-Xmixed mixed mode execution (default)
-Xint interpreted mode execution only
-Xbootclasspath:<directories and zip/jar files separated by ;>
set search path for bootstrap classes and resources
-Xbootclasspath/a:<directories and zip/jar files separated by ;>
append to end of bootstrap class path
-Xbootclasspath/p:<directories and zip/jar files separated by ;>
prepend in front of bootstrap class path
-Xnoclassgc disable class garbage collection
-Xincgc enable incremental garbage collection
-Xloggc:<file> log GC status to a file with time stamps
-Xbatch disable background compilation
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
-Xprof output cpu profiling data
-Xfuture enable strictest checks, anticipating future default
-Xrs reduce use of OS signals by Java/VM (see documentation)
-Xcheck:jni perform additional checks for JNI functions
-Xshare:off do not attempt to use shared class data
-Xshare:auto use shared class data if possible (default)
-Xshare:on require using shared class data, otherwise fail.
The -X options are non-standard and subject to change without notice.
(copy-paste)
This was always the question I had when I was working on one of my application which created massive number of threads per request.
So this is a really good question and there are two aspects of this:
1. Whether my Xms and Xmx value should be same
- Most websites and even oracle docs suggest it to be the same. However, I suggest to have some 10-20% of buffer between those values to give heap resizing an option to your application in case sudden high traffic spikes OR a incidental memory leak.
2. Whether I should start my Application with lower heap size
- So here's the thing - no matter what GC Algo you use (even G1), large heap always has some trade off. The goal is to identify the behavior of your application to what heap size you can allow your GC pauses in terms of latency and throughput.
- For example, if your application has lot of threads (each thread has 1 MB stack in native memory and not in heap) but does not occupy heavy object space, then I suggest have a lower value of Xms.
- If your application creates lot of objects with increasing number of threads, then identify to what value of Xms you can set to tolerate those STW pauses. This means identify the max response time of your incoming requests you can tolerate and according tune the minimum heap size.

Categories