Why is My Java Application Slow?
The toughest IT performance problems to solve today are the ones where a user complains that their application access is slow. An IT administrator must then figure out the cause of the problem: is it the browser, the network, the server, the storage, the cloud infrastructure on which the application is hosted, or the application code? Determining whether the problem is in the application often requires visibility at the code level: which module, which method, which line of code is causing the problem? Slowness can result from many problems in the application code. Inefficient code, which causes excessive looping, poorly designed queries that result in long database access times, insufficient resources for the application, or external services that have slowed down can all cause application slowness. A DZone performance survey found that 43% of application performance issues are due an issue in the application code.
Code Level Visibility Provides the Answer
To troubleshoot problems quickly, IT administrators need to have code-level visibility. At the same time, developers also need the same level of visibility. After all, they need to know where to fix the issue: which module, method and line of code. Code-level visibility also helps identify why the slowness occurred – is it a spin loop, is it a synchronization issue, is it a query issue, external API call, etc.? Profiling tools can be used for providing code-level visibility, but these tools often have high overhead and cannot be used in production environments. To provide code-level visibility in production environments, a couple of approaches can be used:
- Visibility at the virtual machine level: The Java virtual machine (JVM) is the underlying system on which Java application code runs. Modern JVMs provide ways for monitoring tools to track individual threads running in the JVM. At any point, a monitoring tool can take a snapshot of what threads are running, what states are they in (running, waiting, etc.) and what line of code did they last execute. Thread level information often provides the code-level visibility that IT administrators and developers need. If there is a systemic issue that is affecting a number of users, visibility into Java thread statistics is extremely insightful. Such JVM monitoring makes use of instrumentation built into the JVM and therefore, the overhead of getting this level of visibility is very low.
- Visibility at the request level: When a specific user complains that their request was processed slowly, request-level visibility into processing times is essential. This can provide information into:
- How much time was spent in the Java code processing requests
- How much time was spent on database queries and which queries were issued by the specific request
- What other external calls were made and how much time they took
See figure below for a request flow graph showing where exactly time was spent when processing a request. To get this level of visibility, Java transaction tracing using byte-code instrumentation is necessary.
What is byte-code instrumentation?
This is the process of injecting a piece of code during load time of Java classes, which helps to track the flow of a request being processed by code at every step of the application infrastructure. Java application performance monitoring tools use this approach to trace business transactions in real time and isolate the cause of performance slowdowns.
Modern applications are designed in a modular architecture, with multiple tiers for different types of processing tasks – e.g., the front-end processing for display, the middle tier for business logic processing and another tier for backend processing and analytics. When multiple Java application tiers are involved, monitoring each tier independently may not be sufficient. Visibility at the request level requires that the same request is tagged across tiers and a single request flow graph display the time spent in each tier. To achieve this, a tag-and-follow approach must be used. Every tier must analyze the request. Processing data from all the tiers must be collected, aggregated and presented in a single request flow graph so administrators or developers can clearly see how the request processing took place.
eG Enterprise Provides Java Code Visibility
eG Enterprise is an application performance monitoring (APM) solution that helps developers and DevOps professionals easily isolate issues in the application code. eG Enterprise analyzes every single request coming in from a Java-based web application, uses byte-code instrumentation to analyze the request flow and provides code-level visibility to pinpoint the exact line of code or database query that is taking high processing time. With Java code-level visibility, application developers can easily find errors, bugs and inefficiently written code constructs even before the code hits production.