Java Performance Tuning Note (iii) Java program optimization

Source: Internet
Author: User
Tags bitwise locale stringbuffer

Program Code Optimization Essentials:

    • String optimization: Parsing string source, understanding string common methods, using StringBuffer, StringBuilder.
    • List, Map, set Optimization: Analysis commonly used ArrayList, LinkedList, HashMap, TreeMap, Linkedhashmap, set interface, set common method optimization.
    • Using the nio:buffered, channel operation and principle, 0 copies are used.
    • Reference optimizations: Strong references, weak references, soft references, virtual references, Weekhashmap.
    • Optimization techniques: Common code optimization techniques. Not listed here, please refer to the following explanations.

String optimization:

  • String Object Features:

    • End state: The string class is declared final and cannot be overridden by inheritance, protecting the security of the string class and object. The final statement will be compiled by inline before jdk1.5, with a significant increase in performance and a small performance boost after jdk1.5.
    • Chang: string is allocated directly in the constant pool of the method area during compilation, and when we write multiple string objects of the same value, they actually point to different references in the same space. This is very low for object access and creation costs that are often used in this way. It is important to note that when used String a="123";String b=new String("123"); , the compiler creates a new string instance, but the actual value still points to the existing 123 in the constant pool. We can use A.intern (), String's intern method to return a reference in a constant pool, intern is a native local method.
    • Invariance: When a String object is generated, the memory space is permanently unchanged, with the benefit of not locking the synchronization operation in the case of multithreading. You need to be aware of the following code: the String a="123";a="456"; actual "123" is unchanged, just by changing the position of the object's reference.
  • About memory leaks:

    • There are memory leaks in the method:
      String:

        • SUBSTRING (int,int):

      You can see that return is used in the substring method ((Beginindex = = 0) && (endIndex = = value.length))? this:new String (value, b Eginindex, Sublen) construct the truncated new string, and take a look at the constructor of new string three parameters,

      Last string using an array copy This.value = Arrays.copyofrange (value, offset, offset+count); The advantage of this is that space is exchanged for time and a new string is quickly implemented. But when we construct a large string to intercept, and when we do bulk interception, we can think that the byte copy will consume a lot of memory, there is a memory leak problem. This is because the string returned by the three-parameter constructor used by substring is strongly referenced by the outside caller, and the memory copy is large, and the GC cannot be reclaimed, resulting in a outofmemory exception.

        • New String (Char[],int,int): Based on the above analysis, this three-parameter constructor is the culprit, so it is not recommended. Note that the constructor can only be used within a package before jdk1.7, but 1.7 becomes the public method.
        • SUBSTRING (int): As with the two-parameter substring, the single parameter also calls the new String (Char[],int,int), referring to the following code:

          Note that the function calls the substring of the two arguments before jdk1.7.
        • Concat (String): As with substring, a memory leak problem occurs when a new string returned by the use of an jdk1.7 prior to the char[],int,int is used, and the problem does not occur after jdk1.7 algorithm improvements.
        • Replace (Char,char): Like substring, there is a memory leak problem with the new string returned before jdk1.7, which was used before the, jdk1.7 the problem is not improved after the algorithm improves.
        • ValueOf (Char[],int,int): As with substring, there is no improvement to the memory leak issue with new strings that are used before and after jdk1.7, and that are returned with the newer string (Char[],int,int).
        • Copyvalueof (Char[],int,int): Ibid.
        • toLowerCase (Locale): Ibid.
        • toUpperCase (Locale): Ibid.

      Integer:

        • toString (int): As with substring, there is no improvement to the memory leak problem with a new string returned before and after jdk1.7, and with the newly-used strings (Char[],int,int).

      Long:

        • ToString (Long): As with substring, there is no improvement to the memory leak problem with a new string returned before and after jdk1.7, and with the newly-used strings (Char[],int,int).
    • Fix memory leaks: the way to resolve this memory leak is to new String(str.substring(0,100)); construct a new string that touches the original strong reference of substring so that the GC can be recycled normally and no outofmemory exception will occur. For all other calls to the three-parameter constructor, you can also use the new string to re-create instances of the return value to remove strong references, or you can implement these functions yourself to avoid invoking the three-parameter constructor of string.
  • About string segmentation and lookups:

    • Split of String:
      A regular expression is used in the split implementation, and the regular expression is greedy to match when a large number of strings are split, and the efficiency is reduced and deprecated.
    • Use of StringTokenizer:
      StringTokenizer is the JDK's own string segmentation tool, because there is no regular match, so faster, you can see the following source code:

      StringTokenizer just uses the properties of the string itself to slice it.

StringBuffer and StringBuilder:

    • The difference: StringBuffer is thread-safe, all methods of manipulating strings do synchronized operations, and StringBuilder is not thread-safe, so stringbuffer performance is less than StringBuilder.
    • Note: Both StringBuffer and StringBuilder provide constructors with capacity parameters, the primary function is to specify the size of the initialization capacity (save string buffer), when the capacity exceeds capacity, will be expanded to twice times the original size , create a new memory space, copy the memory of the original space into the new memory space, and then free up the original memory space. Because memory copies are time-consuming, it's a good idea to specify the appropriate capacity.
    • Compared with the + number of string: When using the + number splicing string, the compiler will replace the + number new StringBuilder().append() , improve the stitching efficiency, but in a large number of loops splicing, the compiler is not smart enough, each time the generation of new StringBuilder, generating a large number of GC, so performance is not high, It is best to use conact in loops or build your own StringBuffer or StringBuilder.

List interface: because the space is too long, so split, please refer to "Java Performance Optimization note-list interface analysis"//todo
Map Interface: Because the space is too long, so split, please refer to "Java Performance Optimization note-MAPT interface analysis"//todo
set interface: because the space is too long, so split, please refer to "Java Performance Optimization note-set interface analysis"//todo
Radnomaccess Interface: because the space is too long, so split, please refer to "Java Performance Optimization note-radnomaccess interface analysis"//todo

To optimize the collection operation:

    • Duplicate code in the detach loop: The most common is the size () method of the call collection in the loop, and if the collection capacity is constant, be sure to get the size in advance, int size=list.size();for(int i=0;i<size;i++){...} although the size () method returns the internal variable size of the collection, but since size () is the method, there is a stack of functions , it takes time.
    • Reduce method calls: As above, the method call exists on the stack, so it is best not to call the method in the Traversal collection.
    • Omit the same operation: when iterating through a collection, we often get the objects in the collection through the Get method and then manipulate them, and if it is time-consuming to use the get in the loop, the get-out object is saved to the local variable, and then the local variables are manipulated. Repeated operations like this can be extracted.
    • Using iterators: There are many ways to iterate through collections, such as for random access, foreach iterations, iterator iterations, and so on.
      • For random access: The iterations are fairly fast on ArrayList, and the LinkedList based on the linked list is very poor for random access.
      • Iterator iterations: The iterator accesses the collection at the fastest speed, each of which implements the Ietrator iterator interface, each of which optimizes access to the data based on the nature of the collection itself.
      • foreach iteration: Because foreach is compiled into an iterator, it should normally be accessed faster, but there is an extra assignment to the iterator next () return variable after compilation, so the speed slows down.

Using NiO:

    • NiO differs from traditional I/O:
    • Buffer and channel:
    • Buffer principle:
    • Api:
    • 0 Copies:

Reference type:

  • Strong references: Objects that are directly new are strongly referenced, and strongly referenced GC collections are rare, and GC would rather throw a outofmemory exception if it is completely disconnected from GC root.
  • Soft references: Soft references are collected by the GC when the heap approaches the threshold, so long as there is enough memory to keep the reference. Constructs a soft reference using Java.lang.SoftReference.
  • Weak references: Soft references have the lowest reference level, as long as the GC thread is running, the existence of soft references will reclaim weak references, but the GC thread has a low priority, so it will survive for some time. Constructs a weak reference using Java.lang.WeekReference.
  • Virtual Reference: A virtual reference cannot be directly referenced, and when a virtual reference is constructed using Java.lang.PhantomReference, the original strong reference is fetched with the Get () method, and Null is obtained directly because the virtual reference get () method implements NULL returned directly. The only purpose of a virtual reference is to recycle the resource with the reference queue, enter the reference queue when the GC recycles the strong reference, determine whether it is recycled in the reference queue by referencing the return value of the queue's remove () or poll () method, and clean up other resources if recycled.
  • Weekhashmap:weakhashmap is a weakly quoted version of HashMap, where the elements of each key are weakly referenced. The Weakhashmap inheritance weekreference is used to put key in a weak reference, and also call the internal method expungestaleentries () directly or indirectly at get or put, which detects if the weak reference is recycled. If it is recycled, the resource of key is released.
  • Reference queue: When an object changes its accessibility state, a reference to that object may be placed in the reference queue (reference. These queues are used by the garbage collector to communicate with our code about object accessibility changes. Java.lang.ReferenceQueue, passed in soft references, weak references, virtual reference constructors, and when GC threads are recycled, put objects in the reference queue, but they are not purged. Once the reference object is inserted into the queue by the garbage collector, the return value of its Get method will definitely be null, so the object can no longer be resurrected.
    • Public Reference <? Extends under >poll (): Used to remove and return the next reference object in the queue, or null if the queue is empty.
    • Public Referenceremove () throws Interruptedexception: Used to remove and return the next reference object in the queue, which blocks until the queue returns the available reference objects.
    • Public Referenceremove (long timeout) throws Interrupte-dexception: Used to remove and return the next reference object in the queue. The method blocks until the queue returns a usable reference object, or ends after a specified timeout has been exceeded. Returns NULL if the specified timeout is exceeded. If the specified timeout is 0, it means that it will wait indefinitely.

Code Optimization Tips:

    • Exception Optimizations: Never handle exceptions in loops, and looping through the exception stack can be time-consuming to put an exception trap out of the loop. The
    • uses local variables: Local variables are stored in the local variable table of the virtual machine stack, and local variable tables are destroyed as the method is destroyed (out of the stack), so no GC is required. New objects are stored in the heap and require GC reclamation. Static variables are stored in the method area, generated by the Cinit construct at compile time, so the life cycle is the same as the class, and the method area GC is almost not recycled (permanent), so static is much more memory-intensive.
    • bit operations: bit operation speed is the fastest, often used division can be replaced with >>, multiplication can be replaced by <<, shift right one equals to divide by 2, left one equals to multiply by 2.
    • replacing switch:if and switch performance is not a big difference, but sometimes the use of if performance is higher, such as:
switch(num):case1:return1;case2:return2;case3:return3default:return -1

After using if optimization:

int swArr[3]={1,2,3};if(num<1||num>3){    return -1;}else{    return swArr[num];}

Because the random access to the array is very fast, using if is faster than switch. This needs to be optimized according to different business selectivity. In addition, the use of strategy or Factory mode can optimize the Swtich and if judgment, convenient decoupling.

    • Expressions: Expression operations are time-consuming and can be extracted from repetitive expressions within loops without impacting the business into cyclic external variables to be saved, and then used inside the loop. In addition, we often use 24*60*60 such a way to calculate the number of seconds a day, in fact, you can directly write the calculation results in the variable.
    • Expand Loop: Expand the loop to refer to the following code:

Before not expanded:

int num[]=newint[10000];for(int i=0;i<10000;i++){    num[i]=i;}

After expansion:

int num[]=newint[10000];for(int i=0;i<10000;i+=3){    num[i]=i;    num[i+1]=i+1;    num[i+2]=i+2;}

This occurs faster than the pre-deployment, because the loop reduces the step judgment.

    • Using Boolean operations instead of bitwise operations: Bit operations are fast, there are bit logic, but when you use bitwise arithmetic with other logical operations in the judgment, Java's if will complete the execution of the bitwise operation before continuing to judge the other logical operations in the condition. The Boolean operation jumps directly to the IF block after the condition is satisfied, omitting the subsequent logical operation. But usually we only use Boolean arithmetic.
    • Optimize array copy: Use System.arraycopy () because he is native, and it is very efficient to invoke a copy of the operating system implementation.
    • Using buffers: Bufferedinput and bufferedoutput have been described in the previous article, and the same bufferedwrtier and bufferedreader efficiency is also very high. The buffer is used preferentially.
    • Using static methods: Static methods can be used directly without building an instance, and because the method area GC is rarely recycled, and the JVM caches commonly used classes, some common tool classes are more likely to encapsulate static performance. And it is more expressive than function overloading.
    • Use design mode: You can replace the new operation with a prototype mode when the object is larger, especially if the object constructor is time consuming, you can use the prototype schema clone object directly, or you can use the Clone method in Beanutil under Apache Commons. Also in some businesses, you can use the singleton mode, the enjoy meta-mode, proxy mode, Factory mode and other common design patterns to optimize the object generation process, improve performance.

Java Performance Tuning Note (iii) Java program optimization

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.