When application is in use for few minutes then it slowly increases the Used memory value and decreases Free memory value. Application get very slow after few minutes. Why isn't it releasing the memory.
System configuration :
- CPU : Intel(R) Xeon(R) Platinum 8175M CPU @ 2.50GHz (No. of processors : 4 / No. of cpu cores : 8)
- RAM : 30 GB
- OS : CentOS-7
Application configuration :
- java version "1.8.0_171" -- build 1.8.0_171-b11
- apache-tomcat-7.0.55
Tomcat setting
Free -h command
Top command
.
.
Used memory value showing 12 GB occupied and Free memory value showing 600 MB free. I have performed multiple concurrent user searches and run jcmd command to generate heapdump.hprof to analyze the memory usage and observed that heapdump file size is not more than 600 MB.
Used memory is 12 GB and heapdump is of 600 MB - I don't know why memory is not releasing or getting free.
Could any one please advise any read-up on how to setup/configure to improve memory usage for a particular h/w config.
The issue that you are facing is Memory leak
What is it?
In computer science, a memory leak is a type of resource leak that
occurs when a computer program incorrectly manages memory allocations
in such a way that memory which is no longer needed is not released.
as above explained : memory which is no longer needed is not released
When it happens?
when before de-allocation of allocated heap , ref
to allocated heap is disposed.while ref
to heap is disposed then garbage collection won't be able address to allocated heap.on the other word , it won't be able to find orphaned allocated heap.
What does it cause in long running programs while Memory leak happens?
The program will eat RAM , CPU resources
How does it eat ?
The program constantly allocates RAM.But, does not de-allocate it.therefore, Used memory goes high and cause slow & laggy running.
How does it fixed ?
if you are using Android Studio , The intellisense feature of it, will sign Memory leak possible part of code by Yellow Color highlighting.if you hover on highlight, it will pop-out and shows you warning that why does it might cause problem.
As far as i can see you are only setting the permSize. Set the -Xms and -Xmx as well, so that the garbage collector kicks in when those are reached and cleans up the heap memory.
I don't think that there is any issue with the server, it seems the issue is with your code only.
You can use following things to improve the quality of your code if not done already,
In Java8, there is a feature of "try with resources", please use that to close all your connections.
Please check in your code if you have any unnecessary for loop which is just printing some loggers and running every time when the search functionality is executed.
You can also run 'SonarLint' and 'SonarQube' on your code, this will help you to find out Memory leakage in your code.
For testing concurrent searches, you can use jMeter.
I hope this helps.
Have you tried connecting a profiler to check what data types are causing this issue?
A profiler like Visual VM could help you know the status of your heap, what is causing the increase, The right type of Garbage Collector to use.
The reduction in size could be due to, when dumping its heap, the JVM will first run a garbage collection cycle to free any unreachable objects.
If you want to get deeper on how the memory is being used, you should start by checking how the Garbage Collector is doing.
First, the flags you are using don't handle the heap size
-XX:PermSize -XX:MaxPermSize
are used to set size for Permanent Generation. Permanent Generation: The Permanent Generation is where class files are kept. But think of this as the class metadata, not the actual objects, those go to the heap (with some caveats)
Then set your preferences correctly for your JVM with the flags-Xms1024m -Xmx1024m
and enable more logging -verbose:gc -XX:+PrintGCDetails
.
You will get something like this:
Heap
def new generation total 314560K, used 100261K [0x00000000c0000000, 0x00000000d5550000, 0x00000000d5550000)
eden space 279616K, 35% used [0x00000000c0000000, 0x00000000c61e9370, 0x00000000d1110000)
from space 34944K, 0% used [0x00000000d3330000, 0x00000000d3330188, 0x00000000d5550000)
to space 34944K, 0% used [0x00000000d1110000, 0x00000000d1110000, 0x00000000d3330000)
tenured generation total 699072K, used 368281K [0x00000000d5550000, 0x0000000100000000, 0x0000000100000000)
the space 699072K, 52% used [0x00000000d5550000, 0x00000000ebcf65e0, 0x00000000ebcf6600, 0x0000000100000000)
And check the life of your objects, see how they "age" on every GC collection.
These definitions below will help you to understand the lifecycle of objects in the heap better if you already don't
Heap memory
The heap memory is the runtime data area from which the Java VM allocates memory for all class instances and arrays. The heap may be of a fixed or variable size. The garbage collector is an automatic memory management system that reclaims heap memory for objects,
Eden Space: The pool from which memory is initially allocated for most objects.
Survivor Space: The pool containing objects that have survived the garbage collection of the Eden space.
Tenured Generation or Old Gen: The pool containing objects that have existed for some time in the survivor space.
So if you end up with OldGen you, that would trigger a Full GC, and that may indicate you have a memory leak.
This may also cause java.lang.OutOfMemoryError: GC overhead limit exceeded
errors
In this case, I'd inspect further the objects there to find the worm.
Otherwise, it could be that you have a high churn of short lived objects, this happens usually in ETL applications. Try to check your code to avoid instantiating objects as much as possible (check the Flyweight pattern)
And if none of these happens you could say your JVM is healthy.