This article will take about 10 minutes to read.


Source: https://yq.aliyun.com/articles/662001


In Java programs, most of the performance problems are not caused by the Java language, but by the program itself. Developing good coding habits is important and can significantly improve application performance.

1. Try to use singletons in appropriate situations

Using singletons can lighten the load, shorten the load time and improve the load efficiency, but it is not suitable for singletons everywhere.

In simple terms, singletons are mainly applicable to the following three aspects:

First, control the use of resources, through thread synchronization to control the concurrent access of resources;

Second, control the generation of instances to achieve the purpose of saving resources;

Third, control data sharing, allowing multiple unrelated processes or threads to communicate without establishing a direct correlation.

2. Avoid arbitrary use of static variables

When an object is defined as a static variable, the GC usually does not reclaim the memory occupied by the object, such as

At this point, the lifetime of the static variable B is synchronized with that of class A. If class A is not unloaded, the b object is resident in memory until the program terminates.

3. Try to avoid creating Java objects too often

Try to avoid in the method called often, cycle of the new object, because the system not only takes time to create the object, but also to spend time to garbage collection and processing of these objects, in we can control the range, maximum reuse objects, best can use object or array to replace basic data type.

4. Use final modifiers whenever possible

Classes with the final modifier are not derivable.

There are many examples of final applications in the Java core API, such as Java, Lang, and String. Specifying final for the String class prevents the consumer from overwriting the Length () method.

In addition, if a class is final, all the methods of that class are final.

The Java compiler looks for opportunities to inline all final methods (depending on the specific compiler implementation), which can improve performance by an average of 50%.

For example, make getters/setters that access variables in an instance final:

Simple getter/setter methods should be made final. This tells the compiler that the method is not loaded so it can be changed to “inlined”. Example:

5. Use local variables whenever possible

Parameters passed when calling a method and temporary variables created during the call are stored in the Stack, which is faster. Other variables, such as static variables, instance variables, etc., are created in the Heap and are slower.

6, try to deal with the use of both packaging type and basic type

Although wrapper types and primitive types are interchangeable in use, the memory areas they generate are completely different. Primitive types are generated and processed in the stack, while wrapper types are objects and instances are generated in the heap.

In the case of collection-class objects, processing that has object aspects needs applies to wrapper types, while other processing advocates primitive types.

7. Use synchronized cautiously, minimizing the use of synchronize

It is well known that synchronization is expensive and can even cause deadlocks, so try to avoid unnecessary synchronization control.

When the synchronize method is called, it locks the current object so that no other thread can call any other methods on the current object until the method completes execution.

Therefore, the synchronize method is kept to a minimum and method synchronization should be used instead of code block synchronization whenever possible.

9. Try not to use finalize method

As a matter of fact, it is not a good choice to finalize the resource cleaning in Finalize method. Because of the heavy workload of GC, especially when the Young generation memory is recycled, the application program will be paused. Therefore, to finalize the resource cleaning in Finalize method will lead to a heavier burden of GC. Programs run less efficiently.

10. Use primitive data types instead of objects whenever possible

This creates a “hello” string, which is cached by the JVM’s character cache pool;

In addition to creating a String, the String referenced by STR also contains an array of char[], which holds h, E, L, L,o

11. Multithreading should use HashMap and ArrayList as far as possible without thread safety

HashTable, Vector, and so on use synchronization, which degrades performance.

Create a HashMap as reasonably as possible

Make full use of this constructor when creating a large hashMap

By default, initialCapacity is only 16, and loadFactor is 0.75. How much capacity is required? You’d better accurately estimate the optimal size you need. Same thing with Hashtable, same thing with Vectors.

13. Minimize the double calculation of variables

Such as:

Should read:

And avoid using complex expressions in loops, where loop conditions are evaluated repeatedly. If you leave the loop condition values unchanged without using complex expressions, the program will run faster.

14. Try to avoid unnecessary creation

Such as:

Should read:

Try to free resources in finally blocks

Resources used ina program should be released to avoid resource leaks, preferably ina finally block.

Regardless of the result of program execution, the finally block is always executed to ensure that the resource is closed properly.

16, try to use shifts instead of ‘a/b’ operations

“/” is an expensive operation, and using a shift operation would be faster and more efficient

Such as:

Should read:

Note, however, that the use of shifts should be annotated, because the shift operation is not intuitive and difficult to understand.

17. Try to use shifts instead of ‘a*b’

Similarly, for the ‘*’ operation, the shift operation will be faster and more efficient

Such as:

Should read:

18. Try to determine the size of StringBuffer

The constructor of a StringBuffer creates an array of characters of a default size (usually 16).

In use, if this size is exceeded, memory is reallocated, a larger array is created, the original array is copied over, and the old array is discarded.

In most cases, you can specify the size when creating a StringBuffer so that it doesn’t automatically grow when capacity is low, which improves performance.

Such as:

Release references to useless objects as early as possible

Most of the time, the object referenced by a method’s local reference variable will become garbage as the method terminates, so most of the time the program does not need to explicitly set the local reference variable to NULL.

Such as:

Java code

This one is unnecessary. With the completion of the test() method, the scope of the obJ reference variable in the program ends.

But if it is changed to the following:

Java code

It is necessary to set obj to null to release references to Object as soon as possible.

20. Avoid using two-dimensional arrays

Two-dimensional data takes up much more memory than a one-dimensional array, perhaps 10 times more.

21. Try to avoid using split

Avoid using split unless it is absolutely necessary. Because split supports regular expressions, it is relatively inefficient. If it is frequently called tens of millions of times, it will consume a lot of resources. Consider using Apache’s stringutils.split (string,char). Frequent splits can cache results.

ArrayList & LinkedList

One is a linear list, one is a LinkedList, in short, random query using ArrayList as much as possible, ArrayList is better than LinkedList, LinkedList is better than ArrayList by moving Pointers, adding and deleting operations LinkedList, ArrayList also moves data, but this is theoretical analysis, not necessarily true. It is important to understand the data structure of the two, and to act accordingly.

Use system.arrayCopy () instead of looping over arrays

System.arraycopy() is much faster than copying an array through a loop.

Cache frequently used objects as much as possible

Frequently used objects can be cached as much as possible. Arrays or containers of HashMap can be used for caching, but this method may lead to excessive cache occupation and performance deterioration. It is recommended to use some third-party open source tools such as EhCache and Oscache for caching. They basically implement FIFO/FLU and other caching algorithms.

25. Try to avoid very large memory allocations

Sometimes problems are not caused by the state of the heap at the time, but by allocation failures. The allocated blocks must all be contiguous, and as the heap gets fuller, it becomes more difficult to find large contiguous blocks.

26. Use exceptions with caution

When an exception is created, a stack track is collected that describes where the exception was created.

Building these stack traces requires taking a snapshot of the runtime stack, which is very expensive.

When an Exception needs to be created, the JVM has to say: Hold still, I want to save a snapshot of you as you are now, so stop pushing and pushing for a while.

The stack trace contains not just one or two elements in the runtime stack, but every element in that stack.

If you create an Exception, you pay a price, but catching exceptions is inexpensive, so you can wrap the core with a try-catch.

Technically, you can even throw exceptions at will without spending a lot of money.

It is not the throw operation that incurs the performance penalty — although it is somewhat unusual to throw an exception without having previously created it.

The real cost is to create exceptions, and fortunately, good programming habits have taught us that we shouldn’t throw exceptions out of the window.

Exceptions are designed for exceptional situations and should be used with this principle in mind.

27. Reuse objects as much as possible

In the case of strings in particular, use StringBuffer instead of String concatenation because not only will the system spend time generating objects, it may also spend time garbage collecting and processing them later.

Therefore, generating too many objects will have a significant impact on the performance of the program.

28. Do not initialize variables repeatedly

By default, when class constructors are called, Java initializes variables to certain values. All objects are set to null, integer variables to 0, float and double to 0.0, and logical values to false.

This is especially important when a class is derived from another class, because all constructors in the constructor chain are automatically called when an object is created with the new keyword.

One note here is that it is best to place an initial value on a member variable in one method when you need to call another method.

For example, in initXXX(), calling a method directly to assign may throw a null pointer exception because the class has not been initialized, such as: public int state = this.getState().

29. In Java +Oracle application system development, SQL language embedded in Java should be capitalized as far as possible to reduce the parsing burden of Oracle parser.

30, in the Java programming process, database connection, I/O flow operation, after the use, timely close to release resources. Because operating on these large objects can cause a lot of overhead.

It is of great significance to ensure the timely recovery of expired objects

Excessive object creation will consume a large amount of memory in the system, and in serious cases, will lead to memory leaks. Therefore, it is important to ensure that expired objects are recycled in a timely manner.

The JVM’s GC is not very intelligent, so it is recommended that you manually set it to NULL after the object is used.

When using synchronization mechanisms, use method synchronization instead of code block synchronization whenever possible.

33, Do not use a Try/Catch statement in a loop. Place the Try/Catch statement outside the loop

Error is the class that gets system errors, or virtual machine errors.

Not all exceptions can be obtained. If the VM reports an Exception, the Exception cannot be obtained.

34. Using the constructor of a StringBuffer to set its initialization capacity can significantly improve performance

The default size of a StringBuffer is 16, and when the StringBuffer reaches its maximum size, it increases itself to twice its current size +2, that is, 2*n+2.

Whenever a StringBuffer reaches its maximum capacity, it has to create a new array of objects and then copy the old array of objects, which can waste a lot of time. So it’s important to set the StringBuffer to a reasonable initialization capacity.

Use java.util.Vector wisely

Vector is similar to StringBuffer in that each time it expands, all existing elements are assigned to the new storage space.

Vector’s default storage capacity is 10 elements, which is doubled.

Vector.add (index,obj) inserts the element obj into the index position, but the index and subsequent elements are moved down one position (adding one to their index).

Unless necessary, this is not good for performance.

The same rule applies to the remove(int index) method, which removes the element at the specified position in this vector. Move all subsequent elements to the left (subtracting their index by 1).

Returns the element removed from this vector. So deleting the last element of a vector is much cheaper than deleting the first element. Removing all elements is best done with the removeAllElements() method.

To remove an element from a vector, use vector.remove(obj); Instead of having to retrieve the element location and delete it, for example:

Int index = indexOf (obj);

The vector. Remove (index).

Create an instance of an object without using the new key

When an instance of a class is created with the new keyword, all constructors in the constructor chain are automatically called.

But if an object implements the Cloneable interface, we can call its clone() method. The clone() method does not call any class constructors.

Here is a typical implementation of the Factory pattern:

The improved code uses the clone() method:

39, Do not declare arrays as public static final

HaspMap traversal

The hash value is used to extract the corresponding Entry for comparison and obtain the result. After obtaining the Entry value, the key and value are directly obtained.

41, The use of array and ArrayList

Array is the most efficient array, but its capacity is fixed and cannot be changed dynamically. ArrayList can grow dynamically, but at the expense of efficiency.

42. Single threads should use HashMap, ArrayList whenever possible

The use of HashTable and Vector is not recommended unless necessary, as they use synchronization mechanisms and reduce performance.

StringBuffer, StringBuilder

Java.lang.StringBuffer A thread-safe sequence of variable characters. A String buffer similar to String, but not modifiable.

The StringBuilder class should generally be used in preference to this class because it supports all the same operations, but is faster because it does not perform synchronization.

For better performance, when constructing a StringBuffer or StringBuilder, try to specify its capacity.

Of course not if it’s 16 characters or less.

In the same case, using StringBuilder yields only a 10% to 15% performance improvement over using StringBuffer, but at the risk of multithreading insecurity.

All things considered, StringBuffer is recommended.

44. Use primitive data types instead of objects.

45. Using specific analogies to use interfaces is efficient, but structural flexibility is reduced, but modern ides can solve this problem.

46. Consider using static methods

If you don’t need to access the outside of the object, make your method static. It is called faster because it does not require a virtual function guide table.

This is also a good practice because it tells you how to distinguish the properties of a method that does not change the state of the object.

The use of intrinsic GET and SET methods should be avoided as far as possible.

Avoid enumerations, use of floating point numbers.

Here are some examples of practical optimizations:

49. Avoid complex expressions in loop conditions

Without compiler optimization, loop conditions are evaluated repeatedly in loops, and programs run faster if they are left unchanged without complex expressions.

Example:

Correction:

50. Define initial sizes for ‘Vectors’ and ‘Hashtables’

When the JVM augments a Vector, it recreates a larger array, copies the contents of the original array, and finally reclaims the original array.

As you can see, expanding the size of a Vector is a time-consuming process.

In general, the default size of 10 elements is not enough. You’d better be able to accurately estimate the optimal size you need.

Example:

Correction:

Set your own initial size.

Close the Stream ina finally block

Resources used in the program should be released to avoid resource leakage. This is best done ina finally block.

Regardless of the result of program execution, the finally block is always executed to ensure that the resource is closed properly.

52, use ‘system.arrayCopy ()’ instead of looping through arrays

Example:

Correction:

53. Change getters/setters for instance variables to “final”

Simple getter/setter methods should be made final. This tells the compiler that the method is not loaded so it can be changed to “inlined”. Example:

Correction:

54. For constant strings, use ‘String’ instead of ‘StringBuffer’

Constant strings do not need to change their length dynamically.

Example:

Correction: Replace StringBuffer with String, which will reduce runtime overhead and improve performance if it is certain that the String will not change.

55, When adding strings, use ‘ ‘instead of “” if the string has only one character

Example:

Correction:

Replace a one-character string with ‘ ‘

The above is only the performance optimization in Java programming. Most of the performance optimization is a tradeoff in terms of time, efficiency, and code structure level, with both advantages and disadvantages.

Do not take the above content as a dogma, perhaps some of our actual work is applicable, some are not applicable, but also hope to choose according to the actual work scene, live learning and flexible.



, END,

The growth path of programmers

Though the road is long, the journey is sure to come

This article was originally posted on the wechat public account of the same name “The Growth of programmers”, reply to “1024” you know, give a thumbs up.

Reply [520] to receive the best learning method for programmers

Reply to [256] for Java programmer growth plans