I seems to have memory leak problems in my javaFX application, i have been using the net beans profiler tool to help me locate the source of the leaks but i have hit a wall as I'm not sure exactly what I'm doing.
now i have looked at tutorials,and they say to monitor the surviving generations of a object but I'm still unsure what to with this information. I have taken a screenshot of the highest surviving generation objects while i was monitoring my application.
Can someone explain to me what exactly i should be doing with these objects or are they actually causing a memory leak?
A common source of unexpected high memory usage is adding objects to a collection and then not removing them when you are done (I see the image you posted shows a HashMap that may be an issue). The typical solution is to use a collection which will not keep an object alive once all other references to it are gone, see WeakHashMap for more info.
To dig into these types of issues further capture a hrpof (you can use VisualVM, JConsole, etc.) and then analyze it in Eclipse MAT or a similar tool.
Related
I am looking into a potential memory leak (or at least memory waste) in a largish Java based system. The JVM is running with a maximum heap size of 5 GB and 2-3GB heap usage is an expected base line for the application. (There can be peaks that are higher)
In an overload scenario which I am investigating the heap gets filled up. Analyzing the a heap-dump with the "Eclipse MemoryAnalyzer Tool" shows (no surprise) that the heap is entirely used up.
MAT shows 2 potential leak candidates, both roughly retaining 2.5GB: java.lang.Thread and a domain object from the system which is used extensively during transaction processing in the system. All these domain objects are however (no surprise) reachable from the Thread instances. Those threads are processing the transactions, after all. Thus, the 2.5 GB attributed to java.lang.Thread is almost entirely caused by those domain objects. No surprise here.
Listing the object tree of all java.lang.Thread instances and summing up the retained heap of all threads results in 2.5 GB of retained heap.
Where should I look for the other 2.5 GB that are needed to fill up the heap, if they are not reachable from an instance of java.lang.Thread?
- There is nothing in the finalizer queue
- There is not a significant amount of unreachable objects pending GC
I think another way to put this question is: "How do I find all objects that are not reachable from an instance of java.lang.Thread? Maybe an OQL query?, and the other question: "What kind of Objects are there that are not reachable from an instance of java.lang.Thread other then Objects in the Finalizer Queue and unreferenced objects pending GC?"
I too faced the problem with memory leaks at our site,
Use yourkit java profiler which provide lots of information and with its ability you can have a wider image where all the memory is being utilized.
You can find a great tutorial Find Java Memory Leaks with the above tool.
Your question,
"What kind of Objects are there that are not reachable from an instance of java.lang.Thread other then Objects in the Finalizer Queue and unreferenced objects pending GC?"
There are four kinds of object,
Strong reachable, objects that can be reached directly via references from live objects
Weak/Soft reachable, objects that are having weak/Soft reference associated with them
Pending Finalization, objects that are pending for finalization and whose reference can be reached through finalizer queue
Unreachable these are objects that are unreachable from GC roots, but not yet collected
Besides these JVM also uses Native memory whose information you can find on IBM Heap and native memory use by the JVM and Thanks for the memory and according to YourKit the JVM Memory Structure has Non-Heap Memory whose definition according to them is
Also, the JVM has memory other than the heap, referred to as non-heap memory. It is created at the JVM startup and stores per-class structures such as runtime constant pool, field and method data, and the code for methods and constructors, as well as interned Strings.
Since the extra memory is not showing in MAT it's hard to know what to suggest. My apologies if some (or even most) of this is things you already know, I've just tried to pull together everything I could think of.
FindBugs
FindBugs is a static analysis tool that will scan your code looking for common anti-patterns and problems and giving you a nice report on them. It does pick up on a lot of causes of potential memory and resource leaks.
Manual dump
You could try using something like jmap or visualvm to take a heap dump for analysis manually and see if you get different results from letting eclipse do it:
http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jmap.html
http://java.dzone.com/articles/java-heap-dump-are-you-task
Analyzer Quirks
The memory analyzer FAQ:
http://wiki.eclipse.org/MemoryAnalyzer/FAQ
says:
Symptom: When monitoring the memory usage interactively, the used heap size is much bigger than what MAT reports.
During the index creation, the Memory Analyzer removes unreachable objects because the various garbage collector algorithms tend to leave some garbage behind (if the object is too small, moving and re-assigning addresses is to expensive). This should, however, be no more than 3 to 4 percent. If you want to know what objects are removed, enable debug output as explained here: MemoryAnalyzer/FAQ#Enable_Debug_Output
Another reason could be that the heap dump was not written properly. Especially older VM (1.4, 1.5) can have problems if the heap dump is written via jmap.
Enabling debug output will allow you to see what is going on there and confirm there is nothing odd in that area.
Some of these tips may be relevant
http://eclipsesource.com/blogs/2013/01/21/10-tips-for-using-the-eclipse-memory-analyzer/
Use JProfiler and break the heap object count down by class - find which class has lots of instances and start your hunt there.
You can also take a couple of snapshots a short time apart and compare the two heap dumps to see what objects were created during that time. This is particularly handy if you know that a certain action is causing the problem and you want to ignore all the background JVM object noise and just examine the delta.
I have used it with great success to find a memory leak. It isn't free, but it's worth the licence fee.
FYI: I have no affiliation with JProfiler.
Since the extra memory is not showing in MAT it's hard to know what to suggest.
It isn't true. MAT show unreachable objects. Just go to de Preferences and select check box enabling this options. After MAT restart you will see these objects with details. Of course roots to GC will be not available.
Maybe you should look for memory leaks in database connector code or maybe ORM. Because if you are using raw connection library when you don't close cursor you can get potentially memory leak. Also my second thought is also related to database connector. Because some of them (may be not yours) uses native code beneath and this is source of this leak. Due to heavy concurrent usage that makes sens for me. You can check that if you want.
I've started to debug my software using visualVM. I only started to get familliar with this software.
I have memory leak. I found sth that is suspected, but dont know what to make of it.
What is the next step?
This is the way I use Java visualVM to quickly trace memory leaks.
First setup breakpoint or pause in your code at places you want to inspect.
Perform Heap Dumps of your program, use "show in instances view" to view instances in detail for classes you suspect to leak (i.e. obviously too much instances in memory).
Then identify one instance of that class that should have been collected. In the "references" panel, you can see all the objects that refer to your class, right click on "this" and select "nearest GC root", this will show you what references prevent the class from being collected by the GC.
This way you can quickly identify where is the wrong reference and modify your program accordingly to avoid the leak.
Good luck, it's actually very interesting task and if you are a beginner you will learn a lot about how the JVM works
I do not know anything about your application but I would suspect the memory leak can be traced back to a HashMap. Values often accumulate in maps (for caching...).
Also have a look at these similar posts:
VisualVM memory leak detection
How to find memory leaks using visualvm
I am looking into how to use JConsole to detect memory leaks.
I see that in Memory Pool in my MBeans I can define UsageThreashold for my Tenured Generation.
So if my application exceeds this threashold the heap memory becomes red in the Memory tab.
Question: How does this help? I mean how am I supposed to use this setting to analyze my memory? How am I supposed to figure out this value?
In my opinion I don't think that UsageThreashold parameter is the most helpful for you to detect memory leaks (but if someone knows some tricks with it, please do share). In my experience that parameter is more helpful to visually understand if my application is getting way too near my max heap size and I'm in danger of getting an OutOfMemoryException.
Still regarding using JConsole to search for memory leaks, I don't think there's a silver bullet for the process. But what I usually do is the following:
If exists a memory leak, it means that the objects (the ones that are leaking) won't get collected, hence, your Tenured Generation won't fully recover after any amount of GCs.
With the application running I connect JConsole and try to spot a leak by observing the memory tab, if after several computations of my application and also after various GCs occurring (including pressing the Perform GC button, which will result in a full gc) the memory never goes below, or at least to the memory value, it started tracking there's a great possibility that something is leaking. When the leak is big, you can even see a "stair graph" pattern in your memory.
Keep in mind that if your application has long computations running, which may consume memory this analyzes must be done carefully. You must understand when those processes have finished. For example, just run one of those computations and track the total evolution of memory, before, during and afterwards.
Also, I suggest you to try visualVM instead, because it also allows you to create heap dumps, which you can use in order to understand which objects are still in memory and explore the references graph to understand why they are not being collected.
you can use JMAP to see the histogram and/or to create heap dumps and study your memory consumption with tools like Eclipse MAT or YourKit.
JConsole is used more for monitoring and running MBeans and less for analysis and in my expirence JVisualvm is better for that since you can use it for sampling your code and see what methods are CPU consuming.
I have been working on this project on Java with multiple modules. Since quite some time, I have been occasionally getting "java: Out Of Memory" error! I am pretty new to this 'popular' error and wanted to know the general approach to solve such errors.
Also, are there standard tools accepted by the industry to help figure out the cause of such errors?
The modules in my project include every minute polling from a third party (using web service), multi-threading among other things. However, this is just a pointer and I seek a general approach and not something very specific to my project.
Thanks.
Sometimes you just have an class that uses a lot of memory and you need to increase the heap size or make a more space-efficient algorithm. Other times it is a leak and you need to deference objects.
Run jvisualvm (it's included in the JDK).
Connect to your process and try if you can to recreate the
out-of-memory error while keeping an eye on the heap size.
Perform a heap dump when the memory grows large. Search for the
largest objects by size - often that will give you the culprit
class.
Look at the dependencies to see what is holding a references. If it is a memory leak make sure to dereference unneeded objects.
Also, are there standard tools accepted by the industry to help figure out the cause of such errors?
Yes, there are memory profilers such as VisualVM and YourKit. I use the latter extensively, for both CPU and memory profiling, and find it extremely useful. To get some idea of what it's capable of, take a look at this page: link.
If you can't increase the available memory you have to consume less.
Don't keep references to Objects that you don't need at the time of execution (like data you can reload dynamically) and if necessary redesign your flow (e.g. don't process all objects in parallel and do it sequentially) to require less memory at that time. The garbage collection should do the rest for you.
Especially if you load big data objects into memory consider to use a streaming approach if possible. E.g. you don't need to load a whole file into memory if you want to search through it. You can just step through it.
Besides architectural problems you can also have leaks: keeping unintentional references to objects you don't need anymore. Since they are referenced, the garbage collector can't free the memory and you run out of memory at some point. That is probably the #1 reason for OutOfMemoryExceptions and it usually has to do with static references since classes and therefore the statics are usually not unloaded after the first time you touch a class. The internet has many articles on finding / fixing those, e.g. How to Fix Memory Leaks in Java
one tool I know of is MAT
You likely have a memory leak. Finding it is a challenge. Netbeans has some tools to help you profile the VM . You can profile your project and view men usage while it runs. Apache JMeter is also available as a plug-in or you can run it on its own.
JMeter.apache.org
If you get OOM too often, then start java with correct options, get a heap dump and analyze it with jhat or with memory analyzer from eclipse (http://www.eclipse.org/mat/)
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump file>
I'm trying to determine whether or not I have a memory leak in my webapp. I'm using VisualVM and JMeter to load test and watch the heap.
I saved a heap dump to file and downloaded Eclipse Memory Analyzer yesterday...after much frustration with VisualVM, I thought Eclipse would pinpoint the leak, if any, better than VisualVM.
I opened the heap file in Eclipse and ran what they call a Leak Suspects Report. I thought it would point to a particular class in my webapp, but it doesn't. So I have no clue how to use the info its provided in order to find out where in any particular class of mine the leak suspect is.
Here's the results of the Leak Suspect Report for one of my heap dump files.
One instance of "org.apache.catalina.session.StandardManager" loaded by "org.apache.catalina.loader.StandardClassLoader # 0x261bdac0" occupies 16,977,376 (48.54%) bytes. The memory is accumulated in one instance of "java.util.concurrent.ConcurrentHashMap$Segment[]" loaded by "".
Keywords
org.apache.catalina.loader.StandardClassLoader # 0x261bdac0
org.apache.catalina.session.StandardManager
java.util.concurrent.ConcurrentHashMap$Segment[]
The rest of the Details in the report are as shown in the attached image. I hope the image can be expanded for a closer look....
I know that Eclipse is supposed to be really good software. This is my last attempt to use something like this to find a memory leak - I just have very, very, limited knowledge in HOW this software can be used for such. Tutorial and help pages describe things as though you should know what to do after a few clicks... I need more help than that.
While I don't have any experience with using Eclipse for finding leaks, I would ask a question first: How sure are you that you have a memory leak? From your question, it doesn't sound like you are sure you have a leak, but you are testing to see if you do have one. The simplest way to test that would be to start your application, note how much memory it is consuming, have JMeter hit it continuously for 24 hours, and see how much memory it is consuming (probably after executing GC). If your application is consuming a significantly large portion of memory, or has died from an OutOfMemoryError, then you have a memory leak.
If you find that you actually do have a memory leak, then I would first suggest running your application through FindBugs to see if it can find the memory leaks through a quick static analysis. If that doesn't work, then this article (although it is rather old) might help you understand the results given to you by Eclipse.