Mission 1 - JVM scouting
From Java I feel the need The need for speed
This is text version for the first stream of JTop-Gun channel. The link to the video recording:
<link here>
Let's turn and burn...
Getting basic information about JVM
And we start with "Hello world" and put it into sleep :)
package org.jtopgun;
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread.sleep(1_000_000_000);
System.out.println("Hello world!");
}
}
Questions: how many threads are running right now? How much memory does our "Hello world" occupy? What version of JVM is it running? What GC?
JCONSOLE
JDK gives tools to answer all these questions. And basic tool from JDK to get quite a lot of info is
./jconsole
JPS / JCMD
If we don't have graphical interface, let's see at command line tools which are available.
First let's identify PID for our program. Run
./jps
You will see all JVM running on your machine. JPS stands for JVM process state.
And now let's try
./jcmd
You will see a lot of available commands and can play with them using
./jcmd <pid> <command>
GETTING THREAD DUMP
Now let's see current stack trace of our sleeping beauty. Here are our command line options:
./jstack <pid>
./jcmd 10364 Thread.print
Or you could use jconsole and you will see something like

I have 16 threads, but depending on your Java version, JVM vendor, machine, it can be very different.
There will be a different article describing all of them, today we focus on Reference Handler and Finalizer. Why they are needed? Peter Lawrey gives very good answer for that here https://stackoverflow.com/questions/7658670/understanding-the-reference-handler-thread
But in short, GC is creating linked list of references ready to be removed. Reference Handler will put them in appropriate queue, and Finalizer thread will execute code which is in finalize() method.
WHY YOU MUST NOT USE FINALIZE()
Now, let's update our hello world app like that:
package org.jtopgun;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread newThread = new Thread(() -> {
while (true) {
List arrayList = new ArrayList();
System.out.println(arrayList.size());
}
});
newThread.start();
Thread.sleep(1_000_000_000);
}
}
Basically we start creating garbage in second thread quickly and indefinitely, then memory graph will look approximately like that:

Very much expected - garbage is being created and normally removed. Now let's add another class:
package org.jtopgun;
public class ClassWithFinalizer {
@Override
public void finalize() throws InterruptedException {
Thread.sleep(1);//1 milisecond finalize method
}
}
And rerun the application

We see a stable heap growth. Outcome - never use finalize() method :)