JVM

Server-Class Machine Detection

Starting with J2SE 5.0, when an application starts up, the launcher can attempt to detect whether the application is running on a "server-class" machine and, if so, use the Java HotSpot Server Virtual Machine (server VM) instead of the Java HotSpot Client Virtual Machine (client VM). The aim is to improve performance even if no one configures the VM to reflect the application it's running. In general, the server VM starts up more slowly than the client VM, but over time runs more quickly.

Note: For Java SE 6, the definition of a server-class machine is one with at least 2 CPUs and at least 2GB of physical memory. In Java SE 6, server-class detection occurs if neither -server nor -client is specified when launching the application on an i586 or Sparc 32-bit machine running Solaris or Linux. As the following table shows, the i586 Microsoft Windows platform uses the client VM by default. The remaining Sun-supported platforms use only the server VM.

About G1 Garbage Collector, Permanent Generation and Metaspace

By Poonam-Oracle on Mar 19, 2014

We received some questions around the G1 garbage collector and the use of Permanent Generation with it. There seems to be some confusion that the Hotspot JVM does not use permanent generation when G1 is used as the garbage collector. Here’s some clarification:

  • JDK 7: PermGen

Permanent Generation still exists in JDK 7 and its updates, and is used by all the garbage collectors. In JDK7, the effort to remove the permanent generation was started and some parts of the data residing in the permanent generation were moved to either the Java Heap or to the native heap. Permanent generation was not completely removed and it still exists in JDK 7 and its updates. Here's the list of things that were moved out of the permanent generation in JDK7:

Symbols were moved to the native heap

Interned strings were moved to the Java Heap

Class statics were moved to the Java Heap

  • JDK7: G1 and PermGen

With G1 collector, PermGen is collected only at a Full GC which is a stop-the-world (STW) GC. If G1 is running optimally then it does not do Full GCs. G1 invokes the Full GCs only when the PermGen is full or when the application does allocations faster than G1 can concurrently collect garbage.

With CMS garbage collector, we can use option -XX:+CMSClassUnloadingEnabled to collect PermGen space in the CMS concurrent cycle. There is no equivalent option for G1. G1 only collects PermGen during the Full stop-the-world GCs.

We can use options PermSize and MaxPermSize to tune the PermGen space size according to the application needs.

  • JDK8: PermGen

Permanent generation has been completely removed in JDK 8. This work has been done under the bug https://bugs.openjdk.java.net/browse/JDK-6964458. Options PermSize and MaxPermSize have also been removed in JDK 8.

Email to openjdk alias regarding the PermGen elimination project: http://mail.openjdk.java.net/pipermail/hotspot-dev/2012-September/006679.html

  • JDK8: Metaspace

In JDK 8, classes metadata is now stored in the native heap and this space is called Metaspace. There are some new flags added for Metaspace in JDK 8:

  • -XX:MetaspaceSize=<NNN> where <NNN> is the initial amount of space(the initial high-water-mark) allocated for class metadata (in bytes) that may induce a garbage collection to unload classes. The amount is approximate. After the high-water-mark is first reached, the next high-water-mark is managed by the garbage collector
  • -XX:MaxMetaspaceSize=<NNN> where <NNN> is the maximum amount of space to be allocated for class metadata (in bytes). This flag can be used to limit the amount of space allocated for class metadata. This value is approximate. By default there is no limit set.
  • -XX:MinMetaspaceFreeRatio=<NNN> where <NNN> is the minimum percentage of class metadata capacity free after a GC to avoid an increase in the amount of space (high-water-mark) allocated for class metadata that will induce a garbage collection.
  • -XX:MaxMetaspaceFreeRatio=<NNN> where <NNN> is the maximum percentage of class metadata capacity free after a GC to avoid a reduction in the amount of space (high-water-mark) allocated for class metadata that will induce a garbage collection. By default class metadata allocation is only limited by the amount of available native memory. We can use the new option MaxMetaspaceSize to limit the amount of native memory used for the class metadata. It is analogous to MaxPermSize. A garbage collection is induced to collect the dead classloaders and classes when the class metadata usage reaches MetaspaceSize (12Mbytes on the 32bit client VM and 16Mbytes on the 32bit server VM with larger sizes on the 64bit VMs). Set MetaspaceSize to a higher value to delay the induced garbage collections. After an induced garbage collection, the class metadata usage needed to induce the next garbage collection may be increased.

What is a operand stack

It's how the various individual bytecode operations get their input, and how they provide their output.

For instance, consider the iadd operation, which adds two ints together. To use it, you push two values on the stack and then use it:

iload_0     # Push the value from local variable 0 onto the stack
iload_1     # Push the value from local variable 1 onto the stack
iadd        # Pops those off the stack, adds them, and pushes the result
1
2
3

Now the top value on the stack is the sum of those two local variables. The next operation might take that top stack value and store it somewhere, or we might push another value on the stack to do something else.

Suppose you want to add three values together. The stack makes that easy:

iload_0     # Push the value from local variable 0 onto the stack
iload_1     # Push the value from local variable 1 onto the stack
iadd        # Pops those off the stack, adds them, and pushes the result
iload_2     # Push the value from local variable 2 onto the stack
iadd        # Pops those off the stack, adds them, and pushes the result
1
2
3
4
5

Now the top value on the stack is the result of adding together those three local variables.

Let's look at that second example in more detail:

We'll assume:

  • The stack is empty to start with (which is almost never actually true, but we don't care what's on it before we start)
  • Local variable 0 contains 27
  • Local variable 1 contains 10
  • Local variable 2 contains 5 So initially:
+-------+
| stack |
+-------+
+-------+
1
2
3
4

Then we do

iload_0     # Push the value from local variable 0 onto the stack
1

Now we have

+-------+
| stack |
+-------+
|   27  |
+-------+
1
2
3
4
5

Next

iload_1     # Push the value from local variable 1 onto the stack
1
+-------+
| stack |
+-------+
|   10  |
|   27  |
+-------+
1
2
3
4
5
6

Now we do the addition:

iadd        # Pops those off the stack, adds them, and pushes the result
1

It "pops" the 10 and 27 off the stack, adds them together, and pushes the result (37). Now we have:

+-------+
| stack |
+-------+
|   37  |
+-------+
1
2
3
4
5

Time for our third int:

iload_2     # Push the value from local variable 2 onto the stack
1
+-------+
| stack |
+-------+
|    5  |
|   37  |
+-------+
1
2
3
4
5
6

We do our second iadd:

iadd        # Pops those off the stack, adds them, and pushes the result
1

That gives us:

+-------+
| stack |
+-------+
|   42  |
+-------+
1
2
3
4
5