- This series is going to be dedicated to the basic understanding of Java. When ever I find myself asking, "How does this work ?". I will create a blog post and put it here. This series will not be in order so feel free to read what ever post you find most relevant.
- Full disclosure, I do not work at Oracle or on any other JVM development team, so if you see anything wrong please say so in the comments. However, I do post this blog post with high confidence. I referenced chapter 5 of the JVM specification HERE. I also referenced chapter 12 of the Java language specification HERE
This will be a quick little summary of what the JVM is doing when we first run a program. If you don't understand what's going on, don't worry, I will go into more detail later in the post. The JVM starts up by
loadingan initial class by using a
ClassLoader. The JVM then
linksthe initial class and invokes the
public static void main(String  args)method.
I know the above statement was a little confusing but lets break things down a little. When it comes to running Java code, there are 3 main steps that the JVM must partake in:
So lets talk about loading first
During this step, the JVM will delegate the loading of a class or interface to a
ClassLoader. The JVM will provide the class loader with a class's
binary name(just a string of the class's actual name). The class loader will then attempt to locate the appropriate
binary representation(which is just the .class file) with the given binary name. Once the appropriate .class file is found, a Class object will be constructed and stored in the method area of the heap for later usage. The Class object now represents the .class file in memory.
So if we had a class called Testing and ran the command
java Testing, this is what would happen:
1) a class loader is given the binary name of Testing(which is just Testing)
2) the class loader then finds the appropriate
binary representation(which is just the .class file).
Class<Testing>object is created and stored inside the method area of the heap.
- Linking a class or interface involves verifying and preparing that class or interface, its direct superclass, its direct super interfaces, if necessary. Linking also involves resolution of symbolic references in the class or interface, though not necessarily at the same time as the class or interface is verified and prepared.
- So technical jargon aside, the liking process is when our
Class<Testing>object is combined into the run-time state of the JVM so that it can be initialized and executed. The linking process has 3 main steps it follows:
1) Verification : ensures that the code inside the Class object (
Class<Testing> from our example) or interface is structurally correct.
2) Preparation : involves creating the static fields for a class or interface and initializing such fields to their default values
3) Resolution : the process of dynamically determining one or more concrete values from a symbolic reference. Which is just fancy talk for,
loading and linking other classes that the Class object references.
- Now the initialization process is very technical and it is not as clear cut as I would like it to be. Basically, there are a lot of different scenarios in which a class can be
initializedread more about it in the Java language specs HERE and in the JVM specs HERE. However, once a class has successfully been loaded and linked, we can use that class like we would any other class.
- Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on Twitter.