Java Performance Optimization Tools and Techniques for Turbo
Java Performance OptimizationJava is among the most widely used programming languages in the software development world today. Java applications are used within many verticals (banking,telecommunications,healthcare,etc.),and in some cases each vertical suggests a particular set of design optimizations. Many performance-related best practices are common to applications of all kinds. The purpose of this Refcard is to help developers improve application performance in as many business contexts as possible by focusing on the JVM internals,performance tuning principles and best practices,and how to make use of available monitoring and troubleshooting tools. It is possible to define “optimal performance” in different ways,but the basic elements are: the ability of a Java program to perform its computing tasks within the business response time requirements,and the ability of an application to fulfill its business functions under high volume,in a timely manner,with high reliability and low latency. Sometimes the numbers themselves become patternized: for some major websites,a page response time of 500ms maximum per user function is considered optimal. This Refcard will include target numbers when appropriate,but in most cases you will need to decide these on your own,based on business requirements and existing performance benchmarks. JVM INTERNALSFoundationsCode compilation and JITJava byte code interpretation is clearly not as fast as native code executed directly from the host. In order to improve performance,the Hotspot JVM looks for the busiest areas of byte code and compiles these into native,more efficient,machine code (adaptive optimization). Such native code is then stored in the code cache in non-heap memory. Note: most JVM implementations offer ways to disable the JIT compiler (Djava.compiler=NONE). You should only consider disabling such crucial optimization in the event of unexpected JIT problems such as JVM crashes. The following diagram illustrates the Java source code,just-in-time compilation processes and life cycle. Memory spacesThe HotSpot Java Virtual Machine is composed of the following memory spaces. Another important feature of Java is its ability to load your compiled Java classes (bytecode) following the start-up of the JVM. Depending on the size of your application,the class loading process can be intrusive and significantly degrade the performance of your application under high load following a fresh restart. This short-term penalty can also be explained by the fact that the internal JIT compiler has to start over its optimization work following a restart. It is important to note that several improvements were introduced since JDK 1.7,such as the ability for the default JDK class loader to better load classes concurrently. Hot spotsTROUBLESHOOTING AND MONITORINGThe Java garbage collection process is one of the most important contributing factors for optimal application performance. In order to provide efficient garbage collection,the Heap is essentially divided into sub areas. Heap areasGC collectorsChoosing the right collector or GC policy for your application is a determinant factor for optimal application performance,scalability and reliability. Many applications are very sensible to response time latencies,requiring the use of mostly concurrent collectors such as the HotSpot CMS or the IBM GC policy balanced. As a general best practice,it is highly recommended that you determine most suitable GC policy through proper performance and load testing. A comprehensive monitoring strategy should also be implemented in your production environment in order to keep track of the overall JVM performance and identify future areas for improvement. The HotSpot G1 collector is designed to meet user-defined garbage collection (GC) pause time goals with high probability,while achieving high throughput. This latest HotSpot collector essentially partitions the heap into a set of equal-sized heap regions,each a contiguous range of virtual memory. It concentrates its collection and compaction activity on the areas of the heap that are likely to be full of reclaimable objects (garbage first),or in other words on areas with the least amount of “live” objects. Oracle recommends the following use cases or candidates for using the G1 collector,especially for existing applications currently using either the CMS or parallel collectors:
Java Heap SizingIt is important to realize that no GC policy can save your application from an inadequate Java heap sizing. Such exercise involves configuring the minimum and maximum capacity for the various memory spaces such as the Young and Old generations,including the metadata and native memory capacity. As a starting point,here are some recommended guidelines:
Hot spots
Troubleshooting and MonitoringJava concurrency can be defined as the ability to execute several tasks of a program in parallel. For large Java EE systems,this means the capability to execute multiple user business functions concurrently while achieving optimal throughput and performance. Regardless of your hardware capacity or the health of your JVM,Java concurrency problems can bring any application to its knees and severely affect the overall application performance and availability.
Thread Lock ContentionThread lock contention is by far the most common Java concurrency problem that you will observe when assessing the concurrent threads health of your Java application. This problem will manifest itself by the presence of 1...n BLOCKED threads (thread waiting chain) waiting to acquire a lock on a particular object monitor. Depending onthe severity of the issue,lock contention can severely affect your application response time and service availability. Example: Thread lock contention triggered by non-stop attempts to load a missing Java class (ClassNotFoundException) to the default JDK 1.7 ClassLoader.
It is highly recommended that you aggressively assess the presence of such a problem in your environment via proven techniques such as Thread Dump analysis. Typical root causes of this issue can vary from abuse of plain old Java synchronization to legitimate IO blocking or other non-thread safe calls. Lock contention problems are often the “symptoms” of another problem. Java-level DeadlocksTrue Java-level deadlocks,while less common,can also greatly affect the performance and stability of your application. This problem is triggered when two or more threads are blocked forever,waiting for each other. This situation is very different from other more common “day-to-day” thread problems such as lock contention,threads waiting on blocking IO calls etc. A true lock-ordering deadlock can be visualized as per below:
The Oracle HotSpot and IBM JVM implementations provide deadlock detectors for most scenarios,allowing you to quickly identify the culprit threads involved in such condition. Similar to lock contention troubleshooting,it is recommended to use techniques such as thread dump analysis as a starting point.
Once the culprit code is identified,solutions involve addressing the lock-ordering conditions and/or using other available concurrency programming techniques from the JDK such as java.util.concurrent.locks.ReentrantLock,which provides methods such as tryLock(). This approach gives Java developers much more flexibility and ways to prevent deadlock or thread lock “starvation.” Clock Time and CPU BurnIn parallel with the JVM tuning,it is also essential that you review your application behavior,more precisely the highest clock time and CPU burn contributors. When the Java garbage collection and thread concurrency are no longer a pressure point,it is important to drill down into your application code execution patterns and focus on the top response time contributors,referred as clock time. It is also crucial to review the CPU consumption of your application code and Java threads (CPU burn). High CPU utilization (> 75%) should not be assumed to be “normal” (good physical resource utilization). It is often the symptom of inefficientimplementation and/or capacity problems. For large Java EE enterprise applications,it is essential to keep a safe CPU buffer zone in order to deal with unexpected load surges. Stay away from traditional tracing approaches such as adding response time “logging” in your code. Java profiler tools and APM solutions exist precisely to help you with this type of analysis and in a much more efficient and reliable way. For Java production environments lacking a robust APM solution,you can still rely on tools such Java VisualVM,thread dump analysis (via multiple snapshots) and OS CPU per Thread analysis. Finally,do not try to address all problems at the same time. Start by building a list of your top five clock time and CPU burn contributors and explore solutions.
APPLICATION BUDGETINGOther important aspects of your Java applications performance are stability and reliability. This is particularly important for applications operating under a SLA umbrella with typical availability targets of 99.9%. These systems require a high fault-tolerant level,with strict application and resource budgeting in order to prevent domino effect scenarios. This approach prevents for example one business process from using all available physical,middleware,or JVM resources. Hot Spots
Timeout ManagementLack of proper HTTP/HTTPS/TCP IP timeouts between your Java application and external systems can lead to severe performance degradation and outage due to middleware and JVM threads depletion (blocking IO calls). Proper timeout implementation will prevent Java threads from waiting for too long in the event of major slowdown of your external service providers.
TOOLSjstack,native OS signal such as?kill -3?(thread dump snapshots) IBM Monitoring and Diagnostic Tools for Java NOTE: Proper knowledge on how to perform a JVM thread dump analysis is highly recommended <table style="width: 630px;" border="1"> |
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!