Is there a minimum -Xmx setting for Oracle's JVM? It looks like -Xmx2M does provide the application with more than 2 MB of heap size, as the Java Memory MX bean tells me it allocates like 10 MB...
Is there a minimum under which the JVM silently ignores the Xmx setting?
If I run
public static void main(String[] args) {
System.out.println("Heap size is " + Runtime.getRuntime().totalMemory() / 100000 / 10.0 + " MB");
}
with -mx8m on Java 7 update 25 64-bit I get
Heap size is 8.0 MB
but if I run with -mx2m I get
Heap size is 3.2 MB
So it does appear you get slightly more heap than you asked for for very small sizes. However, even for a small mobile device I wouldn't be worrying about every last MB because the JVM itself is much larger (can be over 100 MB of shared memory, thread etc)
i.e. if you can't spare a few MB, you won't be able to run the JVM anyway.
For jvm to start minimum 2mb of heapsize is required. You can set heap size to 0 bytes, but jvm will not start.
And maximum heap size recommended is 1/4 of total ram.
Related
I am profiling a Java process with VisualVM and I found out that while my used heap remains constantly below 100 MB, the heap size keeps increasing to a point at which it is 10 times bigger than the used heap!
Reading from the docs:
By default, the virtual machine grows or shrinks the heap at each
collection to try to keep the proportion of free space to live objects
at each collection within a specific range. This target range is set
as a percentage by the parameters -XX:MinHeapFreeRatio= and
-XX:MaxHeapFreeRatio=, and the total size is bounded below by -Xms and above by -Xmx.
So, consindering that MinHeapFreeRatio and MaxHeapFreeRatio are set to 40% and 70% respectively, why is this happening?
I am running a 32 bit JVM on my system and I am using eclipse for java. I wrote a program to get the heap size as bellow:
public static void main(String[] args) {
long heapSize = Runtime.getRuntime().totalMemory();
System.out.println("current heap size: " + heapSize / 1000000f + " m");
long heapMaxSize = Runtime.getRuntime().maxMemory();
System.out.println("heapMaxsize: " + heapMaxSize / 1000000f + " m");
long heapFreeSize = Runtime.getRuntime().freeMemory();
System.out.println("heap free size: " + heapFreeSize / 1000000f + "m");
System.getProperty("sun.arch.data.model");
System.out.println("JVM is : " + System.getProperty("sun.arch.data.model"));
}
the result is as bellow:
current heap size: 259.52255 m
heapMaxsize: 1037.9592 m
heap free size: 258.0899 m
JVM is : 32
Now I need to increase my heap size memory because most of my programs are complaining about heap size memory. I tried 3 approaches to change and increase the heap size but I got failure:
I also should mention that the total memory of my computer is 8G and I can see from task manager that more than 70% of that is always in use.
Approach one> Java config > java > view >Runtime Parameters> setting this value: -Xmx3g feedback: nothing
Approach two> Going to a specific program> Run COnfigurations>Arguments> -Xmx2048m feedback:
Error occurred during initialization of VM
Could not reserve enough space for 2097152KB object heap
Approach 3> Eclipse> Windows> Preference> Java> Installed JREs> Edit> and in VM Arguments, I types: -Xms256M -Xmx2048M feedback:
Error occurred during initialization of VM
Could not reserve enough space for 2097152KB object heap
Question: I don't know what else I can do and what should I try to increase my heap size?
Does the amount of in use memory which I explained is more that 70% always have any effect on heap?
Please help me!
You are running the 32-bit version of the JVM. To access significantly more memory you will need to switch to the 64-bit JVM.
From the Oracle FAQ:
Why can't I get a larger heap with the 32-bit JVM?
The maximum theoretical heap limit for the 32-bit JVM is 4G. Due to various additional constraints such as available swap, kernel address space usage, memory fragmentation, and VM overhead, in practice the limit can be much lower. On most modern 32-bit Windows systems the maximum heap size will range from 1.4G to 1.6G. On 32-bit Solaris kernels the address space is limited to 2G. On 64-bit operating systems running the 32-bit VM, the max heap size can be higher, approaching 4G on many Solaris systems.
In jvisual vm i see three attributes under Monitor>Heap, i see 3 attributes depicting memory details all with differnt figures
Size : ?
Used :- I believe this is the actual memory used
Max :- I believe this is the max heap size allocated to java process (specified with Xmx)
I am not sure what size actually depicts?
The three attributes can be defined as next:
Size: The actual total reserved heap size
Used: The actual used heap size.
Max: The max size of the Java heap (young generation + tenured generation)
Indeed when you launch your JVM, the initial heap size (can be defined with -Xms) will be the initial total reserved heap size, then according to how your application behaves, it could need to increase the total reserved size until it reaches the max size and if it is still not enough you could get OOME.
Size depicts the heap block size assigned to java process. Try with -Xms 512m or 1024m then your size to start with will be 512m but used memory may be much lower. As soon as used memory grows , heap resizing occurs proactively so that memory can be allocated to live objects.
Its like you have Gas tank of 30 litre max capacity . But you know for now you may just need 20 litres for the trip but actually used in trip is 5 litres
Heap size is actual size of heap your running application has.
Used heap is used portion of heap size.
Max heap size is the maximum value the application's heap size can have (can be defined by the arg option -Xmx).
When monitor memory usage of a java application, you see that heap size may vary during running of the application. It can not be greater than max heap size. For a sample profiling (monitoring of an application), see below image:
Am I right in thinking that when one specifies VM arguments in an IDE (I'm using NetBeans in this instance), that these arguments are only passed when the code is run through the IDE itself?
Essentially, I'd like to specify that when my program runs, the VM's minimum/initial heap size is 2Gb. I can do this using the -Xms2048m command, but I'm wondering if there's some way to achieve this without having to type a command (for the customer's sake).
Even thought I set the VM argument in NetBeans, and Launch4J (I wrap the JAR into an EXE file), when the program boots & outputs the Runtime's total memory size, it always gives ~120Mb.
What am I missing?
Edit: I output the total memory size using...
int mb = 1024 * 1024;
System.out.println("Max Memory: " + Runtime.getRuntime().totalMemory() / mb);
Edit 2: Could one not create a initialising program that takes no arguments, but starts the main program with the relevant VM arguments? Something like...
public class Main {
public static void main(String[] args) {
String execName = new File(new File("").getAbsolutePath()) + "\\Program.exe";
Runtime rt = Runtime.getRuntime();
rt.exec("java -Xms2048m -Xmx4096m -jar " + execName);
}
}
The only way to do this is to have the program start another copy of the program witht eh heap you want. Note: the end user might not want 2 GB e.g.
If they have 32-bit windows they cannot e.g. if their default is only 120 MB, they most likely have a 32-bit windows client JVM which can't be 2 GB. If they have 32 GB or more they might want more than 2 GB.
BTW Gb = Giga-bit, Mb = Mega-bit, GB = Giga Byte. MB = Mega Byte.
No, You can't change the heap size programatically. Command line is the only way
Since the values must be set during JVM initialization,You cannot.
Some Useful discussion on the same on oracle forums.
And on SO :programatically setting max java heap size
Heap is able to shrink after GC iteration if GC decides that there are too many unused heap space allocated. Maybe that is way after your application starts it shows you the same size each time.
And also -Xms seems to set initial size of heap, not minimum
C:\Users\AStybaev>java -X
...
-Xms<size> set initial Java heap size
...
is there limit to increase the max heap size in java? I am wondering if the large heap size can be set as long as the physical memory is available.
For example, if a server has 100G for RAM, then can i set the max heap at 90G? I know that GC will halt the app, but I am just curious.
Thanks.
With a 32 bit JVM, the hard limit would be 4 GB but the actual one would be lower as, at least if you aren't running a 64 bit OS, some space must be left for non heap memory, like the JVM own address space (non java), stacks for all threads, architecture/OS limitations and the likes. A 64 bit JVM has no such limitation so you could set the limit to 90 GB although I wouldn't recommend it for the reason you already pointed.