15

I have Java application, which, unfortunately, begins to consume quite big amounts of memory after some time. To complicate things, it's not only Java application, it is also JavaFX 2 application.

I suspect that there is some memory leak, maybe even in underlying JavaFX calls and native libs.

The ideal solution would be to get a dump of all java objects at some moment (with their memory usage), and then analyze that dump. Is there some way to achieve this?

Rogach
  • 26,050
  • 21
  • 93
  • 172
  • What platform are you working on? Linux, Win, Mac? – Balázs Németh Aug 18 '12 at 12:47
  • @BalázsMáriaNémeth - Linux (Ubuntu 10.10). – Rogach Aug 18 '12 at 12:47
  • Possible duplicate of [How to get a thread and heap dump of a Java process on Windows that's not running in a console](https://stackoverflow.com/questions/407612/how-to-get-a-thread-and-heap-dump-of-a-java-process-on-windows-thats-not-runnin) – Vadzim Nov 07 '19 at 14:20

4 Answers4

18

Use jmap -heap:format=b <process-id> to create a binary dump of the heap which can then be loaded into several tools - my favorite being the "Eclipse Memory Analyzer"

pjklauser
  • 1,156
  • 11
  • 13
6

There are lots of ways to get a heap dump, starting with simple tools like jmap to more fancy stuff like JVisualVM or even commerical tools as JProfiler. Correctly interpreting those dumps can be tricky though, so you might want to post exactly what you are looking for. Are going hunting for a memory leak, or are you interested in getting a general feel for your application?

sarcan
  • 3,145
  • 19
  • 22
  • I'm looking for some memory leaks, maybe even in native libs :( – Rogach Aug 18 '12 at 12:52
  • It will be rather tricky to find a leak if it is indeed caused by the JavaFX classes (though I am not aware of any issues there). If you have access to it, I recommend getting JProfiler for this, though I am sure that other applications (that i may be unaware of) can do the job as well. The basic approach is getting a heap dump, examining fishy looking object populations and using the tool to trace the instances back to their GC roots (something you don't want to do by hand). This feature will basically tell why an instance has not been garbage collected. – sarcan Aug 18 '12 at 12:56
  • I am using jvisalvm now, and judging by the fact that my application has slowly growing heap size, it's not the result of native leaks - but leaks of java objects. Thus I hope that it would be easy to solve. Thanks for your help! – Rogach Aug 18 '12 at 13:10
  • Keep in mind though that a constantly growing heap does not prove a memory leak until you actually get the OOMException. Depending on your garbage collector it might just be uncollected garbage that is left until a full collection is necessary. – sarcan Aug 18 '12 at 13:37
  • Unfortunately, I checked (by forcing GC from jvisualvm) and it doesn't seem to be uncollected garbage. The actual problem is that memory keeps to accumulate even if application sits doing absolutely nothing. – Rogach Aug 18 '12 at 16:26
  • Well it will be doing something if it is accumulating garbage. Have you checked (via JVisualVM) where CPU time is being spent? – sarcan Aug 18 '12 at 16:47
5

You can use jvisualvm. It has plugin to see live memory and get a dump out of it.

Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205
3

I just re-discovered this article (archive.org archive) when researching ways to grab "JVM state right at this moment" - after a heap I pulled with jmap was about half the size of what the MBeans reported. I'll add it for completeness:

su $JVM_OWNER -c "gcore -o /tmp/jvm.core $YOUR_JVM_PID"
su $JVM_OWNER -c "jmap -dump:format=b,file=jvm.hprof /usr/bin/java /tmp/jvm.core"

Requires gdb installed (for gcore) and a JDK installation (for jmap). Also note you'd might need to adjust /usr/bin/java to the path of the JVM used for the process.

mbafford
  • 2,266
  • 1
  • 20
  • 25
mabi
  • 5,279
  • 2
  • 43
  • 78