
This course includes our updated coding exercises so you can practice your skills as you learn.
See a demo
Trace the origins of Java and the JVM, from the green project to cross-platform bytecode execution and the rise of just-in-time compilation and applets.
Explore how the Java Virtual Machine interprets Java bytecode to achieve platform independence, while using just-in-time compilation and hotspot optimization for fast, secure execution.
Navigate the course layout and ui features for site navigation, view sections and lectures, access pdfs and demos, use bookmarks and q&a, and understand copyright and resource policies.
Explore the lifetime of a type in the JVM, focusing on class and interface lifecycles, static and instance initializers, and the order of loading, verification, and initialization.
Explore the lifecycle of a type in the JVM, including loading with the class loader, verification, preparation, resolution, and initialization, plus how super classes and interfaces are handled.
Explore how the Java virtual machine loads classes through the bootstrap, extension, and application class loaders using a parent delegation model, handles first-time access, and uses class objects for reflection.
Explore the linking stage of the JVM, covering verification, preparation, and resolution, including symbolic references, constant pool, dynamic versus static linking, and eager versus lazy loading, followed by initialization.
Explore the lifetime of a type in the JVM through a class initialization demo, covering class loading, static and instance initializers, and compile-time constants.
Explore reflection in Java by introspecting classes, methods, fields, and constructors at runtime; load classes, create instances, invoke methods, and modify fields, with uses in Eclipse, annotations, and dynamic proxies.
Explore three ways to access a class object in Java via object.getClass(), Class.forName, and class literals, covering primitives, arrays, and reflection.
Learn java reflection by accessing class objects via object references and forName, inspecting metadata, and invoking declared methods and constructors like weblink.
Explore the JVM runtime data areas, including the Java heap and metro area class data, stacks, native heap, and direct buffers, for performance tuning and preventing out of memory errors.
Explore the heap and metaspace, where objects and class data reside, and how class loading, method tables, and runtime type information operate, including the Java 8 metaspace shift.
Explore how method tables organize superclass and subclass method references to dispatch instance and static methods at runtime, and how interface references affect slot order and dispatch in the JVM.
Explore how the JVM's garbage collector manages heap memory, prevents memory leaks and dangling references, and uses generational collection and various algorithms to reclaim memory automatically.
Explore how the JVM identifies dead objects using root references, traverses the object graph, and reclaims memory with mark-sweep, mark-sweep-compact, mark-copy, and generational collection.
Explore how to tune the JVM heap with -Xms and -Xmx, enable serial GC, and analyze GC cycles and details to diagnose memory allocation and out-of-memory errors.
Eliminate obsolete object references to prevent memory leaks in Java, illustrated with a stack example, and learn how garbage collectors, generational collection, and monitoring tools avert out-of-memory errors and slowdowns.
Explore how the stack manages method frames, local variables, and execution flow in the JVM, including per-thread stacks, frame lifecycles, and interaction with the heap and garbage collection.
Examine the stack frame of a method, including the local variables array, runtime constant pool, and return address, and how instance or static methods use the operand stack.
Explore the JVM instruction set with invokespecial and invokevirtual, and analyze how opcodes manipulate the operand stack, local variables, and method binding in constructors and main.
Discover how the JVM stores strings using the string pool, and how interning and the intern() method share literals to save memory, with a practical demo.
Use a string builder instead of the plus operator for concatenating multiple strings to avoid quadratic costs; create one builder outside the loop for linear time.
Explore method binding in the JVM, including signature and implementation binding, static versus instance methods, and early versus late binding, with a practical bytecode demo.
Note: You don't have to register for this course if you have already registered for my comprehensive Java course ~ Java In-Depth: Become a Complete Java Engineer!. The Java course includes all the content that is covered in this course. However, it is very likely that this course could be extended while the JVM related content in the Java course may not be extended any further.
To be a complete Java engineer, apart from having a strong background in Java & design patterns, it is also important to have a good understanding of the internal workings of Java Virtual Machine (JVM). Towards this end, this course is about helping you gain a solid understanding of how JVM works. Here is how the course is organized.
In section 1, we start off by discussing about why JVM (and Java) were created and then discuss JVM and it's architecture at a high-level. In the process, we will also take a look at how Just-in-time (JIT) compilation works.
Sections 2 - 4 delve into the real internals of JVM.
In section 2, we discuss the Lifetime of a Type, i.e., we look at what happens to a Class/Interface since the time it is accessed for the very first time. We learn when and how a class is loaded into memory (Class Loading), when classes it is referencing are loaded (Linking), and when its variables are initialized (Initialization). After conceptually introducing the process, everything will be demonstrated in code.
In section 3, we look at the Reflection API where we learn how to introspect (examine) other classes at runtime and even execute those classes. Frameworks like Spring and JUnit internally use reflection extensively. Knowing reflection is critical when we would have to build frameworks and tools that others use. This section includes a coding exercise where a basic unit testing framework is simulated using Reflection API.
In section 4, we look at the different memory areas (runtime data areas) that JVM deals with. Here we will learn about things like method area, heap, method table, garbage collection, stacks and we will also look at some of the Java bytecode instructions too. In one of the demos, we will look at how we can tune the heap size and how it impacts garbage collection process. To learn about bytecode instructions, we will actually disassemble a .class file and we will inspect the bytecode instructions and learn about how they work.
The demo programs are available for download from the resources section of the corresponding lectures.
It is very likely that the course will also be updated to make it as comprehensive and as practical as possible.
Happy Learning.