In this post I want to give a quick guide over the JVM internals. I will describe about memory internals (the naming is following HotSpot, Oracle's JVM, and JVM specification, so the concepts can be applied in many different JVM vendors ). I will also talk some *unix tools that can help to solve a problem. I don't have intent for a deep tutorial and explaining how to tune a JVM, the objective is to give an overview that may help someone which encounter an odd problem with Java and also give some orientation where to get more information. Let's begin! (less talk and more action =) )
In this first part, let's try to understand some basic concepts/terms in JVM internals. Let's start with an overview of JVM memory:
|click to enlarge|
The diagram above summarize the basically structure of the JVM. In the Stack is a memory that each thread have that contains the Frames, like the state of each call you are doing in with that specific thread (each dotted rectangle is representing a thread). This guy you set using the -Xss JVM option (Also, you need to do some calculation to get the memory used by the JVM, one of them is multiplying the number of thread by the size of this memory pool). You can remind this space when you see StackOverFlowError, it happens due the JVM used the whole stack of that thread, so it will kill that thread due the failure to not keep running the process (due some bugs, the JVM can/could stop its own process due a crash, but the JVM stop is not a expected behavior).
There are some shared memory in the JVM. The Method Area (known as PermGen) is the area where the definition of classes and it meta information (for example the JIT references (JIT is the native code generated by the JVM which is faster than interpreted code)) are available. The PermGen can give OutOfMemory when you loaded too many classes. Like other features in the JVM, there are many options that you can use to optimize the throughput/latency.
But one of the most famous part of the JVM is the Heap. It is stored there the live objects. It is very complex (specially to optimize it, there are people who just work monitoring and enhancing the performance of JVM), so I will try to put in a simple way (removing some difficult concepts that it have). Basically when you create any object, the JVM will save it in the Heap, inside the Young area, and due it is very new, it will be in Eden space. If your object is not in use, it will be removed by Garbage Collector (GC) (this happens in all the spaces, only in the Stack space it doesn't). As the time goes, the objects are migrating to another spaces in the Heap. It will move to the Survivor Space (SS#1)(SS#2) and then (finally) to Old/Tenured Space. The expected JVM behavior is that each of those moves between spaces, less objects are removed. There is two special events associate with the Heap, I just called "removed" but there is two types of it (and a lot of things more in the following links): Scavenge and Stop-the-world events. The Scavenge is when the JVM do a normal job (removing objects of the Heap), but in some cases it need to guarantee that no thread will interfere in its job, so all thread stop working to the GC collect some objects in the Heap.
As I said, I will not cover too many details leaving some links and the comments section of this post to you can get further help. I will give some description with the link, that might help giving an preview what you will see.
#1 - http://en.wikipedia.org/wiki/Jvm#Heap - It is a very sumarized overview of the Heap, but the entire wiki page is very nice to you get a bit more familar of what happens inside your JVM. To get more familiar with some term used here and other details see also http://en.wikipedia.org/wiki/Java_performance .
#2 - http://www.slideshare.net/dougqh/jvm-internals-key-note and http://www.slideshare.net/caroljmcdonald/java-garbage-collection-monitoring-and-tuning - Very cool links. They cover most of things you might want to know about the JVM, such as memory spaces, collector's algorithms, JVM tuning and monitoring (the order of the links is due the complexity).
#3 - http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.3 - This is the JVM specification. The link is to the memory section, I would also suggest to take a look into the Table of Contents to give an idea of how big the JVM is http://docs.oracle.com/javase/specs/jvms/se7/html/index.html )
#4 - http://www.slideshare.net/aszegedi/everything-i-ever-learned-about-jvm-performance-tuning-twitter and http://www.slideshare.net/aragozin/garbage-collection-in-jvm-mailru-fin - These links are awesome! Unbelievable that we can find this kidn of thing in the internet =D! There presentes go very deep in the JVM internals subject. It is a good resource to see if you want to tuning a JVM and your Java application. If you like this subject, you can follow the site http://www.javaperformancetuning.com/ .
#5 - http://www.infoq.com/news/2013/03/java-8-permgen-metaspace - This link shows that some internals of JVM are changing in Java 7 (and much more in Java 8)
#6 - http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#available_collectors.selecting - This is a Oracle's guide of how to tune its JVM. See also this blog post https://blogs.oracle.com/jonthecollector/entry/our_collectors .
I have others links that I'd like to share, but I have to dig more in my bookmark.
I will post the next post I will cover problem solving aspects of JVM problems (how to identify and solve most of cases).