Java program – number of threads started, memory size and garbage collectors on JConsole or JVisualVM

I have written and started a simple program:

package com.bawi.threads;

public class MySleepingMainThread {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(10000000);
    }
}

Eclipse compiled the MySleepingMainThread.java to

C:\dev\my-projects\my-java-threads\target\classes\com\bawi\threads>dir
23-Oct-15  16:39               562 MySleepingMainThread.class

and I started that from windows cmd via:

C:\dev\my-projects\my-java-threads\target\classes>java -cp . com.bawi.threads.MySleepingMainThread

Then I got the java pid by jcmd

C:\dev\env\jdk1.8.0_66\bin>jcmd
12784 sun.tools.jcmd.JCmd
9204 com.bawi.threads.MySleepingMainThread

and took the thread dump using jstack:

C:\dev\env\jdk1.8.0_66\bin>jstack -l 9204
2015-10-23 17:09:57
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode):

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00000000589d4000 nid=0x11a0 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x000000005895b800 nid=0x3a78 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x000000005895a000 nid=0x2b44 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x0000000058954800 nid=0x2a04 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000057523000 nid=0x1438 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000057522000 nid=0x1974 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x00000000574c6800 nid=0xbcc in Object.wait() [0x000000005894e000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d5b070b8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x00000000d5b070b8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

   Locked ownable synchronizers:
        - None

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000574bf800 nid=0x1494 in Object.wait() [0x000000005870f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d5b06af8> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
        - locked <0x00000000d5b06af8> (a java.lang.ref.Reference$Lock)

   Locked ownable synchronizers:
        - None

"main" #1 prio=5 os_prio=0 tid=0x00000000021dd800 nid=0x25bc waiting on condition [0x00000000023cf000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at com.bawi.threads.MySleepingMainThread.main(MySleepingMainThread.java:5)

   Locked ownable synchronizers:
        - None

"VM Thread" os_prio=2 tid=0x00000000574b9800 nid=0x498 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x000000000206c000 nid=0x2fc4 runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x000000000206d800 nid=0x14d0 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x000000000206f000 nid=0x14bc runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002070800 nid=0x3540 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x00000000589f3000 nid=0x1af4 waiting on condition

JNI global references: 5

and noticed 15 threads in the listing. These were “main” thread, but also GC task threads (4), VM threads (2), Compiler threads (3), Service thread, Attach Listener, Signal Dispather, Finalizer, Reference Handler. Most of non “main” threads were daemon threads apart from GC and VM threads.

When connecting via jconsole or jvisualvm I got other 11 thread listed: “main”, Attach Listener, Signal Dispather, Finalizer, Reference Handler, and also RMI TCP Accept-0, RMI scheduler(0), RMI TCP Connection to my local machine (3), JMX server connection. Note there were no GC threads mentioned there.

JConsole showed after startup 16MB heap usage (increases to 35MB and the minor gc knocks it down to 5MB after reaching 35MB in eden, each scan taking 12 ms), committed 128MB and max 1.9GB, loaded 1.6k classes (remains constant).

JConsole lists two garbage collectors:

– PS Scavenge (enabled with -XX:+UseParallelGC) – parallel (uses multiple threads) eden/surivor (YOUNG GENERATION) space collector. After first minor scan, the objects were moved from eden to s1; then after second minor scan data from eden and s1 is moved to s0; after third scan objects from eden and s0 are moved to s1.
– PS MarkSweep – parallel (uses multiple threads) OLD GENERATION collector (not same as ConcurrentMarkSweep) (0 collections so far).

Here NOT used OLD GENERATION collector: ConcurrentMarkSweep (enabled with -XX:+UseConcMarkSweepGC) – the concurrent collector that attempts to do most of the garbage collection work in the background without stopping application threads or minimize the pause time (stop-the-world). Note if the concurrent collector fails to keep up with the garbage, it fails over to the serial MarkSweepCompact collector for (just) the next GC.

Jinfo gives me additional information such as

C:\dev\env\jdk1.8.0_66\bin>jinfo.exe 9992
Attaching to process ID 9992, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.66-b17
Java System Properties:

java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.66-b17
sun.boot.library.path = C:\dev\env\jdk1.8.0_66\jre\bin
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = ;
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level = Service Pack 1
sun.java.launcher = SUN_STANDARD
user.script =
user.country = US
user.dir = C:\dev\my-projects\my-java-threads\target\classes
java.vm.specification.name = Java Virtual Machine Specification
java.runtime.version = 1.8.0_66-b17
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = C:\dev\env\jdk1.8.0_66\jre\lib\endorsed
line.separator =

java.io.tmpdir = C:\Users\me\AppData\Local\Temp\
java.vm.specification.vendor = Oracle Corporation
user.variant =
os.name = Windows 7
sun.jnu.encoding = Cp1252
java.library.path = C:\dev\env\jdk1.8.0_66\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\dev\env\jdk1.8.0_66\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\windows\CCM;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files\TortoiseGit\bin;C:\Program Files\TortoiseSVN\bin;.
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 6.1
user.home = C:\Users\me
user.timezone =
java.awt.printerjob = sun.awt.windows.WPrinterJob
file.encoding = Cp1252
java.specification.version = 1.8
user.name = me
java.class.path = .
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = com.bawi.threads.MySleepingMainThread
java.home = C:\dev\env\jdk1.8.0_66\jre
user.language = en
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.8.0_66
java.ext.dirs = C:\dev\env\jdk1.8.0_66\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\extsun.boot.class.path = C:\dev\env\jdk1.8.0_66\jre\lib\resources.jar;C:\dev\env\jdk1.8.0_66\jre\lib\rt.jar;C:\dev\env\jdk1.8.0_66\jre\lib\sunrsasign.jar;C:\dev\env\jdk1.8.0_66\jre\lib\jsse.jar;C:\dev\env\jdk1.8.0_66\jre\lib\jce.jar;C:\dev\env\jdk1.8.0_66\jre\lib\charsets.jar;C:\dev\env\jdk1.8.0_66\jre\lib\jfr.jar;C:\dev\env\jdk1.8.0_66\jre\classes
java.vendor = Oracle Corporation
sun.stderr.encoding = cp437
file.separator = \
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.stdout.encoding = cp437
sun.desktop = windows
sun.cpu.isalist = amd64

VM Flags:
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=134217728 -XX:MaxHeapSize=2130706432 -XX:MaxNewSize=709885952 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=44564480 -XX:OldSize=89653248 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line:

with GC default options -XX:+UseParallelGC, initial heap size 128M and max heap size 2G, new size 42.5MB (EDEN 32.5MB, S1 5MB, S2 5MB), max new size 677 MB (EDEN 676MB, S1 225MB, S2 225MB), old size 85.5MB (85.5 MB init, 1.32 GB max), metaspace (init 9MB, max 1GB)

Max heap size 2G = max new (young) 0.67 GB (2/3 GB) + max OLD 1.32 GB (4/3 GB)
Old max size is twice as big as young.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s