Regarding memory usage of Java Application - java

I have a question regarding memory usage of java web applications..
In Task manager, Tomcat service seems to occupy 8,677,544,000 Bytes of memory
In jvisualvm, memory usage of java application deployed under that tomcat is as follows
Heap:
Used: 2,304,233,184 B
Size: 8,589,934,592 B
Max: 10,737,418,240 B
Permgen:
Used: 80,272,056 B
Size: 536,870,912 B
Max: 536,870,912 B
Memory Parameters in Tomcat's Service.bat file:
-Xms8192m;-Xmx10240m;-XX:PermSize=512m;-XX:MaxPermSize=512m
Now, my question is no matter what I set MaxHeapFreeRatio the free space is not shrinking even though the used space is shrinking at times.
Can anyone, kindly tell me why is this behaving like this.. Is there a way to shrink the free space so that other processes runnning on the system can utilize it?
I am using latest versions of JDK 1.7 & Tomcat 7.

With the parameter -Xms8192m you're telling Tomcat (well, the JVM) to allocate at least 8 GiB of heap space on startup.
The JVisualVM stats support that, but also tell you that around 2 GiB is being used by the application.
Reduce the start-up value to a lower value (start at 2 GiB). Note that if the application needs more heap space, you've told it you can use up to 10 GiB -Xmx10240m so it may be worth trimming this value down too (maybe to 4 GiB).
Obviously, if you start to get OOME's, you'll need to increase the values until the application has enough to run happily (assuming no memory leaks etc.).
Also, note that the process size will always be larger than the heap size as it also includes the perm gen space (-XX:MaxPermSize=512m) and internal memory / libraries for the JVM itself.
Basic examples:
-Xms512m;-Xmx1536m;-XX:PermSize=64m;-XX:MaxPermSize=256m
The minimum values here are 512 MiB heap, 64 MiB perm gen, so the minimum OS process size would be around 600 - 650 MiB.
As the application allocates more space up to the max values (1.5 GiB heap, 256 MiB perm gen) I'd expect the process size to reach about 2 GiB.
Now if we use your values:
-Xms8192m;-Xmx10240m;-XX:PermSize=512m;-XX:MaxPermSize=512m
The minimum values here are 8 GiB heap, 512 MiB perm gen, so the minimum OS process size would be around 8.6 GiB - pretty much exactly what you're seeing.
Using the max values, the process size would reach nearly 11 GiB.

Related

java memory usage outside heap memory

I have java heap size setting max/min defined as 8 GB . System memory is 14 GB .There is no other java process running other than tomcat . I see java using approx 12 GB and hence system goes down . What kind of other things which are consuming more than 4 GB outside of java heap
permsize is 256 mb only .
I got the answer . Our application was using bytearray which consumes outside heap and hence the difference in behavior .
For a 32 bit JDK, Total virtual memory address is 4G size. Ignoring Kernel space at MAX 3G can be used by java and native heap. In-case of 64 bit JDK virtual memory address is infinite. System memory you mentioned is RAM size. System memory and virtual memory are different. Java heap will not expand than specified -Xmx value. If Xmx is set to 8GB it will not expand further when it reaches 8GB and if application did not find space for allocation then java will throw OutOfMemory exception.

JVM heap space allocation is confusing

I have a java application running with a max heap size of 8 GB .
On a 32 GB memory, the slice of Old gen was 7.4 GB(approx) . In a 128 GB memory, the same application gets a slice of Old Gen of 6.2 GB(approx).
I would like to know how this is done by the JVM internally? Is there a math that it uses. Actually , am in the phase of GC tuning and would be helpful if I get to know how this number is arrived by default. I use JDK 1.7.
It does not have to do with the total RAM in the system. The GC ratios affect how much memory can exist in various regions.
-XX:NewRatio=n Ratio of old/new generation sizes. The default value is 2.
-XX:SurvivorRatio=n Ratio of eden/survivor space size. The default value is 8.
-XX:MaxHeapFreeRatio=70 Maximum percentage of heap free after GC to avoid shrinking.
Use the first 2 ratios to tweak the ratio of the heap internally within the VM itself. Use the free heap ratios to tweak the amount of memory that the heap can grow / shrink by.
Recommended reading - Oracle provided GC tuning guide.

Why is my JVM's total memory usage more than 30 times greater than its Xmx value?

I am running a Java application with a maximum heap size of 128 MB (-Xmx128M). It is running to successful completion with no OutOfMemoryError, or any other unhandled exception. Therefore, I am assuming that its actual heap size did stay within the declared limit of 128 MB.
However, when observing the process for this Java application, I am seeing a peak total memory usage of 4,188,548 KB (~4 GB). This is a growth of more than 30 times the controlled maximum size of the heap. Although I understand that this value includes virtual memory allocated that may be significantly greater than the actual physical memory used, it affects hard limits such as those imposed by Sun Grid Engine, and therefore it is meaningful.
How exactly is this possible? I understand that the total memory consumed by the JVM includes quite a bit more than the size of the heap, but I do not understand how it could need several GB of extra memory beyond what the application actually needs to create its objects and perform its computation.
I am using Sun Java 1.6.0.31, on a 64-bit RHEL Linux distribution.
There are several memory sinks besides the Java heap controlled by -Xmx:
Thread stacks
PermGen space
direct ByteBuffers and mapped ByteBuffer
memory allocated by native code / libraries
Without knowing details of your system I would guess, that something uses mapped ByteBuffers.
But you could dig into the issue by examing the output of the pmap command. It lists all memory regions of the process together with the filenames any region is mapped to (if the regions is mapped of course).

Tomcat memory consumption is more than heap + permgen space

I am observing a mismatch in Tomcat RAM consumption between what the OS says and what jVisualVM says.
From htop, the Tomcat JVM is has 993 MB of resident memory
From jVisualVM, the Tomcat JVM is using
Heap Max: 1,070,399,488 B
Heap Size: 298.438.656 B
Heap Used: variable, between 170MB and and 270MB
PermGen Max: 268,435,456 B
PermGen Size: 248,872,960 B
PermGen Used: slightly variable, around 150MB
From my understanding the OS memory consumption should be Heap Size + PermGen Size ~= 522 MB. But that's 471 MB less than what I'm observing.
Anyone got an idea what am I missing here?
PS: I know that my max heap is much higher than what is used, but I'm assuming that should have no effect if the JVM does not use it (i.e. Heap Size is lower).
Thanks!
Marc
From my understanding the OS memory consumption should be Heap Size + PermGen Size ~= 522 MB. But that's 471 MB less than what I'm observing. Anyone got an idea what am I missing here?
If I understand the question what you are seeing is a combination of memory fragmentation and JVM memory overhead in other areas. We often see 2 times the memory usage for our production programs than we would expect to see from our memory settings.
Memory fragmentation can mean that although the JVM thinks that the OS has given it some number of bytes, there is a certain addition number of bytes that had to be given because of memory subsystem optimizations.
In terms of JVM overhead, there are a number of other storage areas that are not included in the standard memory configs. Here's a good discussion about this. To quote:
The following
are examples of things that are not part of the garbage collected heap
and yet are part of the memory required by the process:
Code to implement the JVM
The C manual heap for data structures implementing the JVM
Stacks for all of the threads in the system (app + JVM)
Cached Java bytecode (for libraries and the application)
JITed machine code (for libraries and the application)
Static variables of all loaded classes
The first thing we have to bear in mind is that: JVM process heap (OS process) = Java object heap + [Permanent space + Code generation + Socket buffers + Thread stacks + Direct memory space + JNI code + JNI allocated memory + Garbage collection], where in this "collection" permSpace is usually the bigest chunk.
Given that, I guess the key here is the JVM option -XX:MinFreeHeapRatio=n, where n is from 0 to 100, and it specifies that the heap should be expanded if less than n% of the heap is free. It is usually 40 by default (Sun), so when the JVM allocates memory, it gets enough to get 40% free (this is not applicable if you have -Xms == -Xmx). Its "twin option", -XX:MaxHeapFreeRatio usually defaults to 70 (Sun).
Therefore, in a Sun JVM the ratio of living objects at each garbage collection is kept within 40-70%. If less than 40% of the heap is free after a GC, then the heap is expanded. So assuming you are running a Sun JVM, I would guess that the size of the "java object heap" has reached a peak of about 445Mb, thus producing an expanded "object heap" of about 740 Mb (to guarantee a 40% free). Then, (object heap) + (perm space) = 740 + 250 = 990 Mb.
Maybe you can try to output GC details or use jconsole to verify the evolution of the heap size.
P.S.: when dealing with issues like this, it is good to post OS and JVM details.
During the startup of your application the JVM will reserve memory equal to roughly the size of your Heap Max value (-Xmx) plus a bit more for other stuff. This prevents the JVM from having to go back to the OS to reserve more memory later.
Even if your application is only using 298mb of heap space, there will still be the 993mb reserved with the OS. You will need to read more into reserved vs committed memory.
Most of the articles you will read when talking about garbage collection will refer to allocation from a heap perspective and not the OS level. By reserving the memory at start-up for your application, the garbage collection can work in its own space.
If you need more details, read the article Tuning Garbage Collection
Here are some important exerts from the document
At initialization, a maximum address space is virtually reserved but
not allocated to physical memory unless it is needed.
Also look at section 3.2 (iv) in the document
At initialization of the virtual machine, the entire space for the
heap is reserved. The size of the space reserved can be specified with
the -Xmx option. If the value of the -Xms parameter is smaller than
the value of the -Xmx parameter, not all of the space that is reserved
is immediately committed to the virtual machine.
The OS will report the memory used by the JVM + the memory used by your program. So it will always be higher than what the JVM reports as memory usage. There is a certain amount of memory need by the JVM itself in order execute your program and the OS can't tell the difference.
Unfortunately using the system memory tools isn't a very precise way to track your programs memory consumption. JVM's typically allocate large blocks of memory so object creation is quick, but it doesn't mean your program is consuming that memory.
A better way of knowing what your program is actually doing is to run jconsole and look at the memory usage there. That's a very simple tool for looking at memory that's easy to set up.

Max Heap Size for Tomcat 6 on 64 bit CentOs?

I am running a tomcat 6 instance on a large EC2 instance running CentOS 5.4.
The box has 7.5gb of RAM and is dedicated to running tomcat.
I am trying to give the box 6gb of RAM to use for it's max heap. However I keep getting this error:
Invalid maximum heap size: -Xmx6144m
The specified size exceeds the maximum representable size.
As I drop the amount of RAM I give it I start getting this error instead:
Error occurred during initialization of VM
Could not reserve enough space for object heap
Even with the app running (with xmx3000m) when I run free I have this amount free:
[tomcat#producer1:/usr/share/tomcat/logs] $free
total used free shared buffers cached
Mem: 7864320 1512736 6351584 0 179948 702352
-/+ buffers/cache: 630436 7233884
Swap: 0 0 0
The most I am able to give it is 3000m. This seems unreasonably small. Anyone have any ideas?
Thanks
Do you have 64 bit JDK installed? If you are using a 32 bit JDK it can max access 4GB (theoretically).
As you are planning for 6GB, you require 64bit JDK. Added to that as you have 7.5G, 6GB is a tight no. CentOS requires some memory for kernal, processing other services, SWAP memory from this.
So give a trial & error by increasing heap size from 5G onwards. JDK requires additional memory beyond heap like permgenspace (which is typically 128M - 512M depending on how many libraries/classloaders you have)
Refer to : http://benjchristensen.com/2007/02/16/32-bit-versus-64-bit-jdk-memory-usage/

Categories