After the mid-1990s, Java has also attracted some criticisms while winning. Winner is mainly the Java's cross-platform operability, that is, the so-called "Write Once, Run Anywhere". However, due to the performance of Java, there is still a lot of gaps compared to the Running efficiency, there is a lot of gaps. criticism. For the server-side applications, the performance problem of Java seems to be significant, so that some Java technology, such as JSP, SE RVLET, EJB, etc. are obtained in server-side programming. Very large application, but in fact, Java performance issues still exists on the server. Below I will discuss the performance and implementation efficiency of Java and improve the Java performance of Java.
One. Basic knowledge about performance
1. The definition of performance we need to understand the true meaning of "performance" before we discuss how to improve Java performance. We generally define the following five aspects as the criteria for judging performance. 1) Performance of the calculation --- Which algorithm performs performance is preferably 2) The allocation of the memory ---- The program needs to be assigned how much memory, the efficiency and performance of the runtime. 3) Start time ---- How much time it takes to start. 4) The scalability of the program ----- the performance of the program in the case of user load. 5) Performance's understanding ------ How can users recognize the performance of the program. For different applications, the requirements for performance are also different. For example, most applications take longer time at startup, thereby decreasing the starting time; the application of the server is usually allocated with large memory space, so the requirements for memory are also reduced. However, this is not that the performance of the two aspects can be ignored. Second, the performance of the algorithm is very important for applications that use business logic to transactional operations. In general, the requirements for the application will determine the priority to each performance.
2. How to improve Java performance improve Java performance, generally considering the following four main aspects: (1) Method and mode of programming and model A good design can improve the performance of the program, not only for Java, but also any Programming language. Because it makes full use of various resources, such as memory, CPU, cache, object buffer pools and multithreades, thereby designing high performance and scalable systems. Of course, in order to improve the performance of the program, it is more difficult to change the original design, but the importance of program performance is often higher than the design of the design. Therefore, there should be a good design model and method before the programming begins. (2) Environment of Java deployment. The environment of Java deployment refers to techniques for explaining and executing Java bytecles, usually as follows. That interpretation INSTRUCTIONS (Interpreter Technology), Technical time compiler (Just In Time Compilier Technology), adaptive optimization technique (Adaptive Optimization Technology), dynamic optimization, machine code is compiled ahead technique (Dynamic Optimization, Ahead Of Time Technology) And compile as machine code. These technologies are generally optimized by optimizing thread models, adjusting the size of the stack and stack to optimize Java performance. When considering improving the performance of Java, you must first find bottlenecks that affect Java performance, after confirming the rationality of the design, the Java deployment environment should be adjusted to improve the performance of the Java application by changing some parameters. See Section 2 of the specific content. (3) The implementation of the Java application When discussing the performance issues of the application, most of the programmers will consider the code of the program, which is of course pair, when more important is to find bottleneck code affecting program performance. In order to find these bottleneck code, we generally use some auxiliary tools, such as J Probe, OptimizIzit, VTune, and some analysis tools such as Towerj Performance. These assisted tools can track the time consumed by each function or method in the application, thereby improving the performance of the program. (4) Hardware and operating systems In order to improve the performance of Java applications, use Fast CPUs and more memory, and believe that this is the only way to improve program performance, but this is not the case. Practical experience and facts have proven that only the application performance bottlenecks, there is appropriate way, such as design patterns, deployment, and operating system adjustments, is the most effective. 3. The usual performance bottleneck in the program. All applications have performance bottlenecks. In order to improve the performance of the application, it is necessary to reduce the bottleneck of the program as much as possible. The following is a performance bottleneck that often exists in the Java program.
After you understand these bottlenecks, you can reduce these bottlenecks to improve the performance of Java applications. a) Clear specific requirements for performance Before implementing a project, you must clarify the specific requirements for program performance, such as this application to support 5000 concurrent users, and the response time is within 5 seconds. But it also understands that the requirements for performance should not conflict with other requirements of the program. b) Understanding the performance of the current program You should understand the performance of your application with the gap between the performance requirements of the project. The usual indicator is the number of processing and response time in unit time, and sometimes the utilization of CPU and memory is compared. c) Find the program's performance bottleneck in order to find out the performance bottleneck in the program, usually use some analytics tools, such as TowerJ Application Performance Analyzer or VTune to see and analyze the time consumption of each element in the program stack, thus finding and correcting A bottleneck code with reduced performance, thereby increasing the performance of the program. These tools can also find potential issues such as excessive abnormalities, garbage collection. d) Take appropriate measures to improve performance After the bottleneck code that causes the program performance, we can use the four aspects of the improvement performance, namely design mode, Java code implementation, deployment of Java's environment and Operating systems to improve the performance of the application. The details will be described in detail in the following. e) Improvement of amendments only to improve performance only one aspect that may cause performance reduction, and then the performance of the program is improved, and it should not change multiple aspects, because you will not know Which aspect change has improved the performance of the program, which is not, that is, the program bottleneck is not known. f) Return to step c, continue to work similar to the performance, which has been achieved. two. When the Java deployment environment and compilation technology develops Java applications, first compile Java source programs as unrelated to the platform. These bytes can be performed by various JVM-based technologies. These technologies are mainly divided into two large categories. That is, a technique based on the interpretation and technique based on the pre-compiled as local code. The schematic is as follows:
Specifically can be divided into the following five categories: a) Interpretation instruction technology The structural diagram and execution processes are as follows:
Java's compiler first compiles the Java source file as a bytecode. These bytes are the Java Virtual Machine (JVM) is the machine's instruction code. Then, Java's interpreter continuous loops takes out the bytecode and executes. The advantage of this is that the cross-platform of the Java language can be implemented, and the generated bytecode is also compacted. Some of Java, such as security, dynamics have to be kept; but the disadvantage is that the province's generated bytecode is not optimized, and the speed is slower than all compiled local code. B) Timely Compilation Technology (Just In Time) Timely Compilation Technology is to resolve the instruction interpretation technology is relatively low, and the speed is relatively slow, and the structural drawings are shown below.
Its main change is to compile JAVA's bytecode as machine code before the Java program is executed. Thereby directly executing the machine code directly at runtime without using the bytecode. At the same time, the code also has been partially optimized. The advantage of this is that it greatly improves the performance of the Java program. At the same time, since the results of the compilation are not stored in the program running, the time saving the loader is saved; the disadvantage is that the J IT compiler is optimized for all the code, so a lot of time is also wasted. IBM and Sun provide relevant JIT products. C) Adaptive Optimization Technology (Adaptive Optimization Technology) is not optimized for all bytecodes compared to JIT technology. It tracks the procedure of the program run, thus discovering the code that needs to be optimized, and dynamically optimized the code. For optimized code, take 8 0/20 strategies. In theory, the longer the program is running, the more optimized the code. Its structural diagrams are as follows: The advantage is that adaptive optimization techniques use the information of the program, the performance bottleneck of the programs, thereby improving the performance of the program; its disadvantage is that it may be improperly selected when optimizing, and it may be improperly selected. Performance. Its main products are also IBM, Sun's Hotspot. D) Dynamic Optimization Technology. The original code or bytecode of Java is input, and the output is a mixture of highly optimized executable code and a dynamic library (a DLL file in Window, and the shared library in Unix is a shared library .a .so file). The structure is as follows:
Its advantage is to greatly improve the performance of the program; the disadvantage is to destroy Java's portability and bring a certain hidden danger for Java's security.
three. Optimize the Java program design and encoding, improve some of the methods of Java program performance. Find the bottleneck in the program by using some of the previously described auxiliary tools, and then optimize the code of the bottleneck portion. There are generally two options: optimizing code or changing design methods. We generally choose the latter, because you don't call the following code to improve program performance than call some optimized code. And a well-designed program can streamline the code to improve performance. Some methods and techniques that are often used in the design and encoding of the Java program, and some methods and techniques that are often used in the design and encoding of the Java program. 1. Adjustment of the generation and size of the object. A common problem in the Java program is that there is no function provided by the Java language itself, which often generates a large number of objects (or instances). Since the system not only takes time to generate an object, it may still take time to take the time to garbage recycling and processing. Therefore, excessive objects will have a big impact on the performance of the program. Example 1: About String, StringBuffer, , and Append Java languages provide operations for String type variables. However, if not used, it will affect the performance of the program. As of the following statement: string name = new string ("HuangWeifeng"); System.out.Println (Name "Is My Name"); seemingly very streamlined, it is not the case. In order to generate binary code, the following steps and operations are processed. (1) Generate a new string new string (STR_1); (2) Copy the string. (3) Load the string constant "HuangWeifeng"; (4) Call the string of the architecture; (5) Save the string into an array (starting from position 0) (6) from Java.io The static OUT variable (7) generates a new string buffer variable in the .printStream class New StringBuffer (STR_BUF_1); (8) Copy the string buffer variable (9) Call string buffer (constructor); (10); (10) ) Save the string buffer to an array (starting from position 1) (11) Taking STR_1 as a parameter, calling the Append method in the string buffer class. (12) Loading the string of the constant "IS my name"; (13) Taking STR_3 as the parameter, call the Append method in the string buffer. (14) Execute the toString command for STR_BUF_1. (15) Call the PrintLn method in the OUT variable, output the result. It can be seen that the two lines of simple code generates STR_1, STR_2, STR_3, STR_4, and STR_BUF_1 five object variables. Examples of these generated classes are generally stored in the heap. Piles are initialized for all classes, classes of all classes, while also calling an extremely super-class architecture. These operations are very consumed system resources. Therefore, it is necessary to limit the generation of objects. After modification, the above code can be replaced with the following code.
StringBuffer name = new stringbuffer; system.out.println ("is my name."). TOSTRING ()); the system will perform the following operations. (1) Generate a new string buffer variable new stringbuffer (STR_BUF_1); (2) Copy the string buffer variable (3) load string constant "huangweifeng" (STR_1); (4) call string buffer architecture ( Constructor); (5) Save the string buffer to an array (starting from position 1) (6) Get static OUT variable from the java.io.printStream class to load STR_BUF_1; (8) loading string often " Is my name "(STR_2); (9) Call the Append method in the StringBuffer instance with STR_2. (10) Execute the toString command for STR_BUF_1. (STR_3) (11) Call the PrintLn method in the OUT variable, output the result. It can be seen that the improved code only generates four object variables: STR_1, STR_2, STR_3 and STR_BUF_1. You may feel that less generation of an object will not increase the performance of the program. However, the execution speed of the code segment 2 below will be twice the code segment 1. Since the code segment 1 generates eight objects, the code segment 2 generates only four objects. Code segment 1: String name = new stringbuffer ("huangweifeng"); name = "is my"; name = "name"; code segment 2: stringbuffer name = new stringbuffer ("HuangWeifeng"); name.Append ("is my "); Name.append (" name. "). TOSTRING ();
Therefore, fully utilize the library function provided by Java to optimize the program, which is very important to improve the performance of the Java program. The attention points mainly have the following aspects; (1) use static class variables if the class The variables in the middle will not change with his instance, you can define a static variable, so that all the instances share this variable. Example: Public class foo {someObject SO = New someobject ();} You can define as: public class foo {static homeObject so = new someobject ();} (2) Do not make too much changes to generated objects. For some classes (such as: String class), prefer to regenerate a new object instance without modifying the generated object instance. Example: String name = "huang"; name = "wei"; name = "feng"; the above code generates three String type object instances. The first two immediately need system for garbage collection. If you want to connect to a string, performance will be worse. Because the system will not generate more temporary variables for this. As shown in the first example. (3) When the object is generated, many classes to be assigned to it rationally and the size in Java have its default spatial allocation size. For StringBuffer classes, the default assignment space size is 16 characters. If the spatial size of the StringBU Ffer in the program is not 16 characters, the correct initialization must be performed. (4) Avoid generating objects or variables shorter or shorter life cycle. For this case, an object buffer pool is defined. It is to manage a smaller cost of managing a target buffer pool than frequent generation and recycling objects. (5) Initialization only within the target scope. Java allows you to define and initialize the object anywhere in your code. In this way, it can be initialized only within the range of the object. Thereby saving the overhead of the system. Example: SomeObject SO = New SomeObject (); if (x == 1) THEN {foo = SO.GETXX ();} can be modified to: if (x == 1) Then {SomeObject SO = New SomeObject (); foo = So.Getxx ();
2. Try / catch in an exception (Exception) Java language provides TRY / CATCH to facilitate user capture exceptions to process abnormalities. But if you use improper use, it will also affect the performance of the Java program. Therefore, pay attention to the following two points. (1) Avoid logic to the application using TRY / CATCH If you can use the IF, while, etc., if you do not have a try / catch statement (2), you must do an abnormally processed process, Reuse the existing anomaly objects as much as possible. Those in the abnormal process, generating an abnormal object to consume most of the time. 3. Threading A high-performance application usually uses threads. Because threads make full use of the resources of the system. In other threads, the program can continue to process and run because of the other threads waiting for the hard disk or network read and write. However, it is used to use improper use and will affect the performance of the program. Example 2: Correct use of the Vector class Vector is mainly used to save various types of objects (including the same type and different types of objects). However, in some cases, use the performance of the program to bring performance. This is mainly determined by the two features of the V ECTOR class. First, Vector provides thread safety protection features. Even many methods in the Vector class synchronize. But if you have confirmed that your application is a single thread, the synchronization of these methods is completely unnecessary. Second, when V Ector finds various objects stored, it often spends a lot of time to match the type. These matches are completely unnecessary when these objects are in the same type. Therefore, it is necessary to design a single-threaded, saving a particular type of object class or collection to replace the V ECTOR class. The program used to replace is as follows: public class stringvector {private string [] data; private int count public StringVector () {this (10); // default size is 10} public StringVector (int initialSize) {data = new String [initialSize];} public void add (String str) {// ignore null strings if (str = = NULL) {Return;} EnsureCapacity (count 1); data [count ] = Str;}
private void ensureCapacity (int minCapacity) {int oldCapacity = data.length; if (minCapacity> oldCapacity) {String oldData [] = data; int newCapacity = oldCapacity * 2; data = new String [newCapacity]; System.arraycopy (oldData, 0, DATA, 0, count);}} public void remove (string str) {if (str == null) {return // ignore null str} for (int i = 0; i
The procedures for test are as follows: import java.util.vector; public class testcollection {public static void main (string args []) {testcollection collect = new testCollection (); if (args.length == 0 ) {System.Out.println ("usage: java testcollection); system.exit (1);} if (args [0] .Equals (" vector ") {Vector store = new vector ); long start = system.currenttimemillis (); for (int i = 0; i <1000000; i ) {store.addelement ("string");} long finish = system.currenttimemillis (); system.out.println (Finish-start); start = system.currenttimemillis (); for (int i = 0; i <1000000; i ) {string result = (string) Store.Elementat (i);} finish = system.currenttimemillis () System.out.Println (FINISH-START));} else if (args [0] .Equals ("stringvector")) {stringVector store = new stringVector (); long start = system.currenttimemillis (); for INT i = 0; i <1000000; i ) {store.add ("string");} long finish = system.currenttimemillis (); system.out.println; start = SY Stem.currentTimeMillis (); for (int i = 0; i <1000000; i ) {string result = store.getstringat (i);} finish = system.currenttimemillis (); system.out.println (Finish-start) );}}} / * * * * * * * * * * TestCollection.java * * * * * * * * * * * * * * * / Test results are as follows (assuming standard The time is 1, the smaller the performance, the better:
For the operation of thread, pay attention to the following aspects. (1) Prevent excessive synchronization As shown above, unnecessary synchronization often causes a decline in program performance. Therefore, if the program is a single thread, you must not use synchronization. (2) Synchronous method instead of synchronizing the entire code segment to synchronize a method or function to synchronize the entire code segment. (3) Increase the mechanism for each object using multiple "lock". Generally, each object has only one "lock", which indicates that "dead lock" occurs if two threads perform two different synchronization methods of an object. Even if these two methods do not share any resources. To avoid this problem, you can implement "multi-lock" mechanisms to an object. As follows: class foo {private static int var1; private static Object lock1 = new Object (); private static int var2; private static Object lock2 = new Object (); public static void increment1 () {synchronized (lock1) {var1 }}} public static void increment2 () {synchronized (lock2) {var2 ;}}} 4. Input and output (I / O) input and output include many aspects, but involving the most is the read and write operations of the hard disk, network, or database. For read and write operations, it is divided into cache and no cache; for the operation of the database, there can be several types of J DBC drivers to choose. But no matter what, it will affect the performance of the program. Therefore, it is necessary to pay attention to the following: (1) Use the input and output buffer as much as possible to use the cache. However, if you want to refresh the cache, it is recommended not to use a cache. (2) Output stream and Unicode strings When using Output Stream and Unicode strings, the WRITE class has a big overhead. Because it is to implement Unicode to byte (Byte) conversion. Therefore, if possible, the conversion is implemented before using the WRITE class, or use the O UtputStream class instead of the Writer class. (3) When serialization is serialized as a class or object when serialization, for those atomic or reconstructed powdery, it is to recognize the TRANSIENT type. This will not be serialized each time. If these serialized objects are transmitted over the network, this small change has great improvement in performance. (4) Using Cache For objects or data that are often used and unclear, you can store it in a cache. This will increase the speed of access. This is especially important for the result set returned from the database. (5) Provide four ways to access the database using the JDBC Drive (Driver) Java Java. There are two kinds of JDBC drivers. One is a local drive out of Java; the other is a complete Java drive. Specifically, which one is to be determined according to the J ava deployment environment and the application itself.
5. Some other experiences and techniques (1) Use local variables (2) to avoid setting or calling variables in the same class during the same class. (3) Avoid using System.ArrayCopy when copying a large amount of data using Static, Final, Private, and other keywords (5) as possible using Static, Final, Private, and so on. ()command.