My simple goal is to monitor the memory usage of a Java application, so I can be warned when the application becomes dangerously close to throwing OutOfMemoryError .
Yes, just to say, but coming up with the right solution seems very difficult. Some of the complicating factors are:
- There are different areas of the heap, each of which can raise an
OutOfMemoryError :permgen space that has its own size limit (set via -XX:MaxPermSize= )- Total heap space (set via
-Xmx )
- A VM can allocate almost the entire heap before worrying about garbage collection. If the application uses a lot of soft links, then in fact this will definitely happen. Thus, simply a high percentage of heap distribution does not mean that the application is close to throwing an
OutOfMemoryError . - It would be nice if
System.gc() guaranteed that the VM would return the whole possibly returned object (an object with no link and / or weakly referenced), but it is not. Therefore, calling System.gc() and then Runtime.freeMemory() not reliable. - Objects queued for finalization take up memory, but (usually) are freed after they are completed. So did the finalizer thread get to them or didn't affect the (obvious) memory usage (VM starts the finalizer as the last indent action before throwing OOM? Don't look like that. )
- The internal code also takes up memory, and using it too much can lead to OOM (this is not a likely case in my particular application, but adds another complication to the overall image).
So, what is a good and reliable way to answer the question: Is a Java application for metaling OutOfMemoryError ?
In other words, suppose application version X is working fine and has no memory leak, but version X + 1 has a slow, unrecognized memory leak. I would like this warning signal to be warned before version X + 1 OutOfMemoryError , but I would like the same monitoring to not give false positives for version X. Some configuration may be necessary to configure this monitoring - this is normal.
One possible answer might be something like: what is the maximum, compared to the past N full "GCs", of using the heap immediately after starting the GC? If this value exceeds X% of the total allocated memory, then beep.
The idea is to define "application memory usage" as a simple number, such as a percentage or even something like LOW, MEDIUM or HIGH, and then track that value.
The jstat command gives a ton of relevant information, the problem boils down to a simple answer and the elimination of false positives (or negative) caused by the complicating factors listed above.
source share