The Garbage Collection Handbook: The Art of Automatic Memory Management (Chapman & Hall/CRC Applied Algorithms and Data Structures series)
All
Stack Overflow 8
This Year
Stack Overflow 2
This Month
Stack Overflow 1
I am assuming that the 680768 kB of memory that you are reporting is from an OS tool like ps or task manager. The total amount of memory used by the JVM is not causing the temporary freezing of the app. The likely cause of the pause is that the JVM Garbage collector is running a full GC which will suspend all threads in the JVM which the full GC is running (unless you have a concurrent gc configured).
You should run the JVM running the playframework with -verbosegc -XX:+PrintGCDetails to see what the GC is doing.
Your question "Does the Play Framework need that much memory" can not be answered because the amount of memory used will depend on what your application is doing on a pre request basis. Also the JVM will let the heap run down and then do a GC cycle to clean up the Heap. A well behaved JVM app should show a saw tooth pattern on the GC graph.
I don't know which JVM you are using if you are using the hotspot VM read the JVM tunning guide. http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html You generally need to understand the following GC concepts before reading the JVM tuning guide for the guide to make sense.
http://www.amazon.com/Garbage-Collection-Handbook-Management-Algorithms/dp/1420082795/ is probably a good book on this subject
A couple of free tools that ship with the hotspot JVM that you can use include jconsole, and jvisualvm. jvisualvm has a nice plugin called VisualGC which is great at learning how the hotspot vm manages memory.
I've wrote the Qish garbage collector (not really maintained any more, but feel free to ask). It is a free copying generational GC for C (with some coding styles restrictions).
The GCC MELT [meta-]plugin (free, GPLv3 licensed), providing a high level language, MELT, to extend the GCC compiler, also has a copying generational GC above the existing
Ggc
garbage collector of GCC. Look into gcc/melt-runtime.cWith generational copying GC, generating the application's code in C is quite useful. See my DSL2011 paper on MELT
Feel free to ask me more, I love talking about my GC-s.
Of course, reading the Garbage Collection Handbook: The Art of Automatic Memory Management (Jones, Hosking, Moss) [ISBN-13: 978-1420082791] is a must
(added in 2017)
Look also into Ravenbrook's Memory Pool System which can be used for generational GC.
Look also into the runtime of Ocaml, which has a good (single-threaded) generational GC.
PS. Debugging a generational copying GC is painful.
If you look for a vendor-independent resource revealing and thoroughly describing all the various GC algorithms ever researched/designed, I recommend:
Garbage collection is a pretty complicated topic, and while you could learn all the details about this, I think what’s happening in your case is pretty simple.
Sun’s Garbage Collection Tuning guide, under the “Explicit Garbage Collection” heading, warns:
That guide says that the default time between garbage collections is one minute, but the sun.rmi Properties reference, under
sun.rmi.dgc.server.gcInterval
says:If you’re seeing major collections every hour in one application but not another, it’s probably because the application is using RMI, possibly only internally, and you haven’t added
-XX:+DisableExplicitGC
to the startup flags.Disable explicit GC, or test this hypothesis by setting
-Dsun.rmi.dgc.server.gcInterval=7200000
and observing if GCs happen every two hours instead.I believe it is the memory allocated by the shared library which you are dlclose-ing which is staying, and you have no simple way to remove it (because you don't know which other parts of your process -e.g. which others dlopen-ed libraries is using it). If you want to understand more, read a good book on Garbage Collection, or at least the wikipage. Being a memory useful to the process is a global property of the entire process, not of particular libraries.
However, some libraries have conventions regarding memory usage, and might offer you the facility of cleaning up memory and resources. Others libraries don't release resources. Some libraries give you the ability to give as parameters the allocation routines they are calling.
You might consider using the Boehm conservative garbage collector or chase your leaks with an utility like valgrind.
Good luck, since your problem has no general solution. Perhaps telling us more about the actual libraries you are dlopen-ing might help.
And of course, there is the work-around of restarting from time to time your process.
Out of various resources I have compiled a sanity checklist that I use to analyze GC behavior and performance of my applications. These guidelines are general and apply to any vendor-specific JVM but contain also HotspotVM-specific information for illustration.
Disable Explicit GC. Explicit GC is a bad coding practice, it never helps. Use
-XX:+DisableExplicitGC
.Enable Full GC logging. Lightweight yet powerful.
-XX:+PrintTenuringDistribution -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log -XX:+HeapDumpOnOutOfMemoryError -Xloggc:gc.log -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -showversion
Consider additional means of collecting information about your GC. Logging is fine but there are sometimes available lightweight command-line tools that will give you even more insight. Eg.
jstat
for Hotspot which will show you occupation/capacity of Eden, Survivor and Old Gen.Collect Class Histograms These are lightweigh and will show you the content of the heap. You can take snapshots whenever you notice some strange GC activity, or you can take them before/after Full GC:
-XX:+PrintClassHistogramBeforeFullGC -XX:+PrintClassHistogramAfterFullGC.
Consider different GC Algorithm. The VMs usually come with several different GC implementations that are providing various tradeoffs : throughput, footprint, pause-less/short-pauses, real-time, etc. Consider the options you have and pick the one that suites your needs.
Beware of finalize(). Check that GC keeps up with classes using
finalize()
. The execution of this method may be quite costly and this can impact GC and application throughput.Heap Dumps. This is the first step that is heavyweight and will impact the running application. Collect the Heap Dump to further study the heap content or to confirm a hypothesis observed in step 4.
Resources used:
Books:
Talks/Articles:
Mailing Lists: