- Lab
-
Libraries: If you want this lab, consider one of these libraries.
- Core Tech
Guided: Profiling and Diagnosing Java SE Applications
In this Code Lab, you will use standard JDK profiling and diagnostic tools to monitor performance and troubleshoot issues in a Java application. You will identify and fix a CPU bottleneck and a memory leak.
Lab Info
Table of Contents
-
Challenge
Introduction and Setup
Welcome to the Guided Code Lab on Profiling and Diagnosing Java SE Applications!
In this lab, you'll act as a performance engineer tasked with fixing a slow and memory-hungry Java application. You will use standard, powerful tools that come with the JDK to find and fix the root causes of these problems.
The Scenario
The
DataProcessorapplication continuously loads and processes batches of customer data. However, it contains two common but critical bugs:- A CPU bottleneck that makes the application unnecessarily slow.
- A memory leak that causes its memory footprint to grow indefinitely, leading to an eventual crash.
Your Goal
Your goal is to use profiling tools to understand the application's behavior, identify the faulty code, and implement fixes to make the application both fast and stable. You will be guided on how to use tools like Java VisualVM to analyze CPU, memory, and threads.
info> This lab experience was developed by the Pluralsight team using Forge, an internally developed AI tool utilizing Gemini technology. All sections were verified by human experts for accuracy prior to publication. For issue reporting, please contact us.
-
Challenge
Step 2: Baseline Profiling and Initial Analysis
Before you can fix anything, you need to understand the problem. The first step is to compile and run the application to observe its current, problematic behavior. You will also add some basic logging to get a rough idea of what's happening with the application's memory.
After compiling, you would typically run the application and connect a profiler like VisualVM. You'd notice two things right away:
- The CPU usage is very high.
- The memory usage, as reported by your logging, steadily increases and never goes down.
-
Challenge
Step 3: Analyze and Fix the CPU Bottleneck
Running a CPU profiler (like the Sampler in VisualVM) on the application would quickly reveal that a significant amount of time is spent in the
DataProcessor.generateReportmethod. This is what's known as a 'hotspot'.Looking at the code, the cause is the use of the
+=operator to concatenate strings in a loop. In Java, strings are immutable. This means that each time you use+=, a new string object is created in memory, and the contents of the old and new parts are copied over. Doing this repeatedly in a loop is extremely inefficient.The standard solution is to use
StringBuilder, which is a mutable sequence of characters designed specifically for this scenario. -
Challenge
Step 4: Diagnose and Fix the Memory Leak
Now that the CPU is no longer maxed out, the memory issue becomes more prominent. If you were to watch the application's heap in VisualVM's Monitor tab, you'd see the 'Used heap' size grow in a sawtooth pattern, but the bottom of the 'teeth' would constantly rise. This indicates that objects are surviving garbage collection—a classic sign of a memory leak.
A heap dump analysis would show that millions of
com.example.Customerobjects are being kept alive by a static list:CUSTOMER_CACHE. The application adds customers to this cache in every cycle but never removes them. The garbage collector cannot reclaim the memory from these objects because a static variable holds a permanent reference to them.Your task is to fix this by clearing the cache after the objects inside it are no longer needed.
-
Challenge
Step 5: Investigate Thread Behavior
The final area of diagnostics is thread analysis. Unresponsive applications are often caused by threads that are deadlocked or stuck waiting for a resource indefinitely. You can investigate this by taking a thread dump.
A thread dump is a snapshot of the state of all threads in the JVM. Each thread will be in a specific state, such as:
RUNNABLE: The thread is actively executing code.BLOCKED: The thread is waiting to acquire a lock.WAITING/TIMED_WAITING: The thread is waiting for another thread or a specific amount of time.
To practice this, you will add a method that simulates a blocking operation, which will cause the main thread to enter a
TIMED_WAITINGstate. You could then use a tool likejcmd <pid> Thread.printor VisualVM's Threads tab to see this in action. -
Challenge
Conclusion
Congratulations on completing the lab!
You have successfully diagnosed and fixed major performance and stability issues in a Java application. You have learned how to:
- Capture CPU, memory, and thread metrics: You added logging for memory and learned where to look in profiling tools for key metrics.
- Diagnose memory leaks and performance bottlenecks: You used conceptual profiling data to identify a CPU hotspot (
Stringconcatenation) and a memory leak (a static collection that is never cleared). - Apply profiling data to improve application health: You refactored the inefficient code and patched the leak, resulting in a fast and stable application.
These skills are fundamental for any professional Java developer responsible for building and maintaining robust, high-performance systems.
About the author
Real skill practice before real-world application
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Learn by doing
Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.
Follow your guide
All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.
Turn time into mastery
On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.