29 key points to help you complete Java code optimization _java

Source: Internet
Author: User
Tags garbage collection int size memory usage modifier sessions try catch stringbuffer

Optimize programs through Java code specifications, optimize memory usage, and prevent memory leaks

The resources available to the program (memory, CPU time, network bandwidth, etc.) are limited, and the purpose of optimization is to allow the program to complete the scheduled tasks with as few resources as possible. Optimization typically involves two things: reducing the size of your code and increasing the efficiency of your code. The main discussion in this article is how to improve the efficiency of your code.
In Java programs, most of the reason for performance problems is not in the Java language, but in the program itself. It is important to develop good code writing habits, such as using java.lang.String classes and Java.util.Vector classes correctly and skillfully, which can significantly improve program performance. Let's analyze the problem in detail.

1. Classes that specify the final modifier of the class with the final modifier as far as possible are not derived.
In the Java Core API, there are many examples of final application, such as java.lang.String. Specifying final for the string class prevents people from overwriting the length () method. In addition, if you specify that a class is final, all methods of that class are final. The Java compiler looks for the opportunity to inline (inline) all final methods (this is related to the specific compiler implementation). This will increase performance by an average of 50%.

2, reuse objects as much as possible.
In particular, in the use of String objects, StringBuffer is used instead of strings concatenation. Since the system not only takes time to generate objects, it may also take time to garbage collect and process these objects later. Therefore, generating too many objects will have a significant effect on the performance of the program.

3. Use local variables as much as possible, the parameters passed when the method is invoked, and the temporary variables created in the call are saved in the stack (stack) faster.
Other variables, such as static variables, instance variables, and so on, are created in the heap (Heap) in a slower speed. In addition, local variables may be further optimized depending on the specific compiler/JVM. See Using stack variables whenever possible.

4, do not repeat the initialization of the variable
By default, when the constructor of a class is invoked, Java initializes the variable to the determined value: All objects are set to NULL, the integer variable (byte, short, int, long) is set to 0,float and the double variable is set to 0.0, and the logical value is set to False. This should be especially noted when a class derives from another class, because when an object is created with the new keyword, all constructors in the chain of the constructor are invoked automatically.

5, in Java + Oracle Application system development,Java Embedded SQL statements as far as possible use uppercase form , to reduce the resolution of the Oracle Parser burden.

6, in the Java programming process, the database connection, I/O flow operation must be careful, after use, even close to release resources.
Because the operation of these large objects will cause a large system overhead, a slight carelessness, can lead to serious consequences.

7, because the JVM has its own GC mechanism, does not need the program developer's excessive consideration, reduced the developer to some extent the burden, but also omitted the hidden danger, excessively creates the object to consume the system the massive memory, will cause the memory leak seriously, therefore, guarantees the expiration object's timely recovery to have the important significance .
The JVM reclaims garbage on the condition that the object is not referenced; however, the JVM's GC is not very witty, and even if the object satisfies the garbage collection condition it is not necessarily recycled immediately. Therefore, we recommend that the object should be manually set to NULL when it is used.

8, in the use of synchronization mechanism, should try to use method synchronization instead of code block synchronization.

9, minimize the duplication of the calculation of variables
For example: for (int i = 0;i < list.size i + +) {
...
}
Should be replaced by:
for (int i = 0,int len = list.size (); i < Len i + +) {
...
}

10, as far as possible the adoption of lazy loading strategy, that is, when the need to start creating.

For example: String str = "AAA";
if (i = = 1) {
List.add (str);
}
Should be replaced by:
if (i = = 1) {
String str = "AAA";
List.add (str);
}

11, careful use of abnormal

Exceptions are bad for performance. Throwing an exception begins by creating a new object. The constructor of the Throwable interface calls the local (Native) method named Fillinstacktrace (), and the Fillinstacktrace () method checks the stack to collect call tracking information. Whenever an exception is thrown, the VM must adjust the call stack because a new object is created during the process. Exceptions can only be used for error handling and should not be used to control the process.

12, do not use in the cycle:

Try {
catch () {
}
It should be placed at the outermost layer.

13, the use of StringBuffer:

StringBuffer represents a mutable, writable string.
There are three construction methods:
StringBuffer (); 16-character space assigned by default
StringBuffer (int size); Space to allocate size characters
StringBuffer (String str); Allocate 16 characters +str.length () character space
You can use the StringBuffer constructor to set its initialization capacity, which can significantly improve performance.

The constructor mentioned here is stringbuffer (int length), and the length parameter represents the number of characters the current stringbuffer can hold. You can also use the ensurecapacity (int minimumcapacity) method to set its capacity after the StringBuffer object is created. First let's look at the default behavior of StringBuffer, and then find a better way to improve performance.
StringBuffer maintains an array of characters internally, and when you use the default constructor to create a StringBuffer object, because the initialization character length is not set, the StringBuffer capacity is initialized to 16 characters, That means the default capacity is 16 characters. When StringBuffer reaches its maximum capacity, it increases its capacity to the current twice-fold plus 2, which is (2* old value +2). If you use the default value, and then append the character to it after initialization, it will increase the capacity to 34 (2*16+2) when you append to the 16th character, and increase the capacity to 70 (2*34+2) when appended to 34 characters. Whatever it takes to reach its maximum capacity it will have to create a new character array and then stringbuffer the old and new characters again-which is too expensive. So it's wrong to always set a reasonable initialization capacity value for StringBuffer, which can result in immediate performance gains. The role of the adjustment of the StringBuffer initialization process is evident. Therefore, using a suitable capacity value to initialize StringBuffer is always the best advice.

14, reasonable use of Java class Java.util.Vector.

Simply put, a vector is an array of java.lang.Object instances. A vector is similar to an array, and its elements can be accessed through an integer-indexed index. However, after the vector type object is created, the size of the object can be expanded and shrunk based on the addition or deletion of the element. Consider the following example of adding elements to a vector:
Object BJ = new Object ();
Vector v = new vector (100000);
for (int i=0;
i<100000; i++) {v.add (0,obj);}

The above code is bad for performance unless there is absolutely enough reason to require that the new element be inserted in front of the vector each time. In the default constructor, the initial storage capacity of a vector is 10 elements, and if the new element is joined with insufficient storage capacity, the storage capacity is doubled at a later time. The vector class, like the object StringBuffer class, replicates all existing elements to the new storage space each time the storage capability is extended. The following code fragment is a few orders of magnitude faster than the previous example:
Object BJ = new Object ();
Vector v = new vector (100000);
for (int i=0; i<100000; i++) {v.add (obj);}

The same rule applies to the Remove () method of the vector class. Because there is no "gap" between the elements in the vector, deleting any other element except the last element causes the elements behind the deleted element to move forward. That is, removing the last element from the vector is several times lower than deleting the first element "overhead."

Suppose you want to remove all elements from the previous vector, we can use this code:
for (int i=0; i<100000; i++)
{
V.remove (0);
}

However, the preceding code is several orders of magnitude slower than the following:
for (int i=0; i<100000; i++)
{
V.remove (V.size ()-1);
}

The best way to remove all elements from a vector-type Object V is:
V.removeallelements ();

Suppose the vector type Object v contains the string "Hello". Consider the following code, which removes the "Hello" string from this vector:
String s = "Hello";
int i = V.indexof (s);
if (I!=-1) v.remove (s);

The code doesn't look like a mistake, but it's also bad for performance. In this code, the IndexOf () method searches the V for a sequential search for the string "Hello", and the Remove (s) method is searched in the same order. The improved version is:
String s = "Hello";
int i = V.indexof (s);
if (I!=-1) v.remove (i);

In this release, we can avoid a second search by giving the exact index of the element to be deleted directly in the Remove () method. A better version is:
String s = "Hello"; V.remove (s);

Finally, let's look at a code fragment about the vector class:
for (int i=0; I++;i < V.length)

If v contains 100,000 elements, the code fragment calls the V.size () method 100,000 times. Although the size method is a simple method, it still requires the overhead of a method call, at least for the JVM to configure and clear the stack environment. In this case, the code inside the for loop does not modify the size of the vector type Object V in any way, so the above code is best rewritten in the following form:
int size = V.size (); for (int i=0; I++;i<size)

While this is a simple change, it still wins performance. After all, every CPU cycle is valuable.

15. Use the system.arraycopy () command when copying large amounts of data.

16, code refactoring: Enhance the readability of the code .
For example:

public class Shopcart {
private List carts;
... public void Add (Object item) {
if (carts = = null) {
carts = new ArrayList ();
}
Crts.add (item);
}
public void Remove (Object item) {
if (carts. Contains (item)) {
Carts.remove (item)
}
}
Public List getcarts () {
//returns read-only list return
collections.unmodifiablelist (carts);
}

This method is not recommended
//this.getcarts (). Add (item);
}

17, do not use the New keyword to create a class instance

When you create an instance of a class with the new keyword, all constructors in the chain of the constructor are invoked automatically. But if an object implements the Cloneable interface, we can call its clone () method. The Clone () method does not call any class constructors.
In situations where design patterns are used, if you create objects in Factory mode, it is simple to use the Clone () method instead to create a new object instance. For example, the following is a typical implementation of the factory pattern:
public static Credit Getnewcredit () {
Return to new credit ();
}
The improved code uses the Clone () method, as follows:
private static Credit Basecredit = new Credit ();
public static Credit Getnewcredit () {
return (Credit) Basecredit.clone ();
}
The above ideas are also useful for array processing.

18, multiplication and division

Consider the following code:
for (val = 0; Val < 100000 Val +=5) {
Alterx = val * 8; Myresult = val * 2;
}
Using shift operations to replace multiplication operations can greatly improve performance. Here is the modified code:
for (val = 0; Val < 100000; val = 5) {
Alterx = Val << 3; Myresult = Val << 1;
}
The modified code is no longer multiplied by 8, instead using an equivalent left 3-bit operation, with 1 bits per left being multiplied by 2. Accordingly, the right 1-bit operation is the equivalent of dividing by 2. It is worth mentioning that, although the shift operation is fast, but may make the code more difficult to understand, so it is best to add some comments.

19, in the JSP page to close the useless session.

A common misconception is that the session is created when there is client access, but the fact is that it is not created until a server-side program invokes a statement such as Httpservletrequest.getsession (true), noting that if the JSP does not display the use <> closes session, the JSP file is automatically added to the servlet when it is translated as a statement httpsession sessions = Httpservletrequest.getsession (true); This is also the implicit in the JSP in the history of the session object. Because session consumes memory resources, you should close it in all JSPs if you do not intend to use it.
For pages that do not need to track session state, turning off an automatically created session can save some resources. Use the following Page directive: <%@ page session= "false"%>

20, JDBC and I/O

If your application needs access to a large dataset, you should consider using block extraction. By default, JDBC extracts 32 rows of data at a time. For example, if we were to traverse a 5000-row recordset, JDBC must call the database 157 times to extract all the data. If you change the block size to 512, the number of calls to the database is reduced to 10 times.

21. servlet and Memory usage
Many developers randomly store large amounts of information in user sessions. At some point, objects saved in the session are not recycled by the garbage collection mechanism in a timely manner. In terms of performance, the typical symptom is that the user feels the system slows down periodically, but cannot attribute the reason to any particular component. If you monitor the JVM's heap space, it behaves as if the memory footprint is abnormally fluctuating.
There are two main ways to solve this type of memory problem. The first approach is to implement the Httpsessionbindinglistener interface in all the beans that are scoped to the session. In this way, the resources used by the bean can be explicitly freed as long as the Valueunbound () method is implemented.

Another way is to void the conversation as quickly as possible. Most application servers have an option to set session invalidation intervals. Alternatively, you can programmatically invoke the Setmaxinactiveinterval () method of the session, which is used to set the maximum interval, in seconds, that the servlet container allows for client requests before a voided session.

22, use the buffer mark

Some application servers have added a JSP-oriented buffer tag function. For example, BEA's WebLogic server supports this feature from version 6.0, and the Open Symphony Project also supports this feature. The JSP buffer tag can either buffer the page fragment or buffer the entire page. When the JSP page executes, if the target fragment is already buffered, the code that generates the fragment does not have to be executed. The page-level buffer captures the request for the specified URL and buffers the entire results page. This feature is extremely useful for shopping baskets, directories, and the home page of the portal site. For such applications, page-level buffering can save the results of the page execution for subsequent requests.

23, select the appropriate reference mechanism

In a typical JSP application system, the header, footer parts are often extracted, and then introduced to the page header, footer. Currently, there are two main ways to introduce external resources into JSP pages: include directives, and include actions.
Include directives: For example, <%@ include file= "copyright.html"%>. The directive introduces the specified resource at compile time. Before compiling, a page with an include directive and a specified resource are merged into a single file. The referenced external resource is determined at compile time, and it is more efficient to determine the resource than the runtime.
Include actions: For example, <jsp:include page= "copyright.jsp"/>. This action introduces the results generated after the specified page is executed. Because it is completed at run time, the control of output results is more flexible. However, it is only cost-effective to use the include action when the referenced content changes frequently, or the referenced page cannot be determined until the request for the main page is not present.

24, timely removal of the session no longer needed

To purge sessions that are no longer active, many application servers have a default session timeout, typically 30 minutes. When the application server needs to save more sessions, if the memory capacity is insufficient, the operating system will transfer part of the memory data to disk, and the application server may dump some inactive sessions to disk according to the "Most Frequently used" (Most recently Used) algorithm, and may even throw out "out-of-memory" Abnormal. In a large scale system, the cost of a serialized session is expensive. When the session is no longer needed, the Httpsession.invalidate () method should be called in time to clear the session. The Httpsession.invalidate () method can usually be invoked on the application's exit page.

25, do not declare the array as: public static final.

26. Discussion on traversal efficiency of HashMap

The traversal of key and value pairs in HashMap is often encountered, as in the following two ways: map<string, string[]> paramap = new

Hashmap<string, string[]> ();
....//The first cycle
set<string> appfielddefids = Paramap.keyset ()
, and so on. for (String appfielddefid:appfielddefids) {
string[] values = Paramap.get (APPFIELDDEFID);
......
}

The second loop
for (entry<string, string[]> entry:paraMap.entrySet ()) {
String Appfielddefid = Entry.getkey ();
string[] values = Entry.getvalue ();
.......
}

The first implementation is less efficient than the second implementation.
The analysis is as follows set<string> Appfielddefids = Paramap.keyset (); is to get keyset from HashMap first.

The code is as follows:

Public set<k> keyset () {
set<k> ks = keyset;
return (KS!= null KS: (keyset = new Keyset ()));
}

Private class Keyset extends Abstractset<k> {public
iterator<k> iterator () {return
Newkeyiterator ();
}
public int size () {return
size;
}
Public Boolean contains (Object o) {return
containskey (o);
}
public boolean remove (Object o) {return
HashMap.this.removeEntryForKey (o)!= null;
}
public void Clear () {
HashMap.this.clear ();
}
}

In fact, it returns a private class keyset, which inherits from Abstractset and implements the set interface.

And look at the syntax of the for/in cycle.
for (declaration:expression)
Statement

In the implementation phase is translated into the following types
for (iterator<e> #i = (expression). iterator (); #i. Hashnext ();) {
Declaration = #i. Next ();
Statement
}

Therefore, the Hashmap.keyset () is called in the first for statement for (String appfielddefid:appfielddefids). Iterator ()

And this method calls the Newkeyiterator ()

Iterator<k> Newkeyiterator () {
return new Keyiterator ();
}
Private class Keyiterator extends Hashiterator<k> {
Public K Next () {
Return NextEntry (). Getkey ();
}
}

So in the for, you call the
The iterator used in the second loop for (entry<string, string[]> Entry:paraMap.entrySet ()) is an internal

Class

Private class Entryiterator extends Hashiterator<map.entry<k,v>> {
Public map.entry<k,v> Next () {
return NextEntry ();
}
}

At this point, the first loop gets the key, the second loop gets the HashMap entry efficiency is the second loop that comes out of the loop. You can take the key and value values directly and the first loop or use the HashMap get (Object key) To fetch the value, now look at the HashMap get (Object key) method
Public V get (Object key) {
Object k = masknull (key);
int hash = hash (k);
int i = indexfor (hash, table.length); Entry[] Table
entry<k,v> e = table;
while (true) {
if (E = = null)
return null;
if (E.hash = = Hash && eq (k, E.key))
return e.value;
e = E.next;
}
}
In fact, the hash value is used to take out the corresponding entry to do the results, so use the first loop equivalent to two times into the HashMap entry

And the second loop obtains the value of the entry and then takes the key and value directly, and the efficiency is higher than the first cycle. In fact, according to the concept of the map should also be a second loop better, it is the key and value pairs, the key and value separate operation here is not a good choice.

27, the use of Array (array) and arrylist

Array ([]): most efficient, but its capacity is fixed and cannot be dynamically changed;
ArrayList: Capacity can grow dynamically, but at the expense of efficiency;
Based on efficiency and type checking, use array as much as possible, and you cannot determine the size of the array before using arraylist!
ArrayList is a complex version of array
The ArrayList internally encapsulates an object-type array, which, in general terms, has no essential difference, and even ArrayList many methods, such as index, INDEXOF, Contains, Sort is the corresponding method of directly calling array on the basis of an internal array.
When ArrayList to an object, discard the type information, all objects are masked to object, the type is not checked at compile time, but the runtime will make an error.
Note: Support for generics is included in Jdk5, and type checking is already available when using ArrayList.
From this point of view, the difference between ArrayList and array is mainly due to the efficiency of dynamic capacity increase

28. Use HashMap and ArrayList as much as possible , unless necessary, the use of hashtable and vectors is not recommended, which results in performance overhead due to the use of synchronization mechanisms.

29, the difference between StringBuffer and StringBuilder:

Java.lang.StringBuffer a sequence of variable characters that is thread safe. A string buffer similar to strings, but cannot be modified.

StringBuilder. As opposed to this class, the Java.lang.StringBuilder class should generally be used preferentially because it supports all the same operations, but is faster because it does not perform synchronization. For better performance, you should specify its capacity as much as possible when constructing stirngbuffer or Stirngbuilder. Of course, if you operate a string that is no more than 16 characters long, it is not necessary. Using Stirngbuilder in the same situation can only achieve a 10%-15% performance boost compared to using stringbuffer, but it risks multiple thread insecurity. And in the reality of modular programming, a programmer in charge of a module may not necessarily be able to determine clearly whether the module will run in a multi-threaded environment, so: unless you are sure that your system's bottleneck is on StringBuffer and that your module will not run in multithreaded mode, StringBuffer, please.

Other supplements:

1, in time to clear the object no longer used, set to NULL
2, as far as possible using final,static and other keywords
3. Use buffered objects whenever possible

How to optimize your code to make Java source files and compiled class files smaller
1 use inheritance as much as possible, and the more you inherit, the less code you have to write.
2 to open the Java compiler optimization options: javac-o This option removes the line number from the class file and can
Some private, static,final method is declared as inline method call
3 to extract the common code
4 Do not initialize a large array, although initializing an array in Java code is just a line of code, but
The compiled code is a line of code that inserts an array of elements, so if you have a large amount of data that needs to exist in the array
, you can put the data in a string and then parse the string into the array at run time
The 5th type of object takes up a lot of space, and if you want to store a large number of date objects, consider storing it as
Long, and then converted to date type when used
6 class name, method name and variable name as much as possible using a short name, you can consider using Hashjava, Jobe, obfuscate and Jshrink tools to automatically complete this work
7 define static final type variables to interface
8 arithmetic operations can be moved left/right operations do not use * and/operation, the same operation does not count many times

2. Do not initialize variables two times
Java initializes the variable to a known value by invoking the unique class constructor. All objects are set to Null,integers (Byte, short, int, long) set to 0,float and double set to 0.0,boolean variable set to False. This is especially important for classes that extend from other classes, which are called automatically by all a series of constructors when an object is created with a new keyword.
3. Let the class be final in any possible place
A class that is marked final cannot be extended. There are a number of examples of this technology in the core Java API, such as java.lang.String. Marking the string class as final prevents developers from creating a method of length that they implement themselves.
More to the point, if the class is final, the method of all classes is final. The Java compiler may inline all of the methods (this relies on the implementation of the compiler). In my tests, I've seen an average performance increase of 50%.

9. Exceptions are thrown where they need to be thrown, and try catch can be consolidated to integrate

try { 
some.method1 ();//difficult for Javac 
} catch (Method1exception e) {//and the JVM runtime 
//Handle Exception 1//To optimize this 
}//code 
try { 
some.method2 (); 
} catch (Method2exception e) { 
//Han Dle exception 2 
}

try { 
some.method3 () 
} catch (Method3exception e) { 
//Handle exception 3
   }

Code is more easily optimized by compilers

try { 
some.method1 ();//easier to optimize 
some.method2 (); 
Some.method3 (); 
} catch (Method1exception e) { 
//Handle exception 1 
} catch (Method2exception e) { 
//Handle exception-2
   } catch (Method3exception e) { 
//Handle exception 3 
}


Optimization for loops
Replace ...
for (int i = 0; i < collection.size (); i++) {
...
}

With ...
for (int i = 0, n = collection.size (); i < n; i++) {
...
}


5, in Java + Oracle Application system development, Java Embedded SQL statements as far as possible use uppercase form, to reduce the resolution of the Oracle Parser burden.

10, as far as possible the adoption of lazy loading strategy, that is, when the need to start creating.
For example: String str = "AAA";
if (i = = 1) {
List.add (str);
}
Should be replaced by:
if (i = = 1) {
String str = "AAA";
List.add (str);
}

12, do not use in the cycle:
Try {
catch () {
}
It should be placed at the outermost

The above mentioned is the entire content of this article, I hope to be able to help you Java optimization.

Please take a moment to share the article with your friends or leave a comment. We will sincerely thank you for your support!

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.