In Java programs in general, memory is a topic of more headache. Although the JVM can intelligently reclaim resources through the GC mechanism, due to the release of the memory is the JVM is operating, improper use will cause Java program memory continues to grow, until the end of the Oom (out of Memery)
So, how do you make memory optimizations for Java? On the one hand, you can optimize configuration from the JVM layer by adjusting some of the JVM's configuration (memory, GC, etc.), and on the other hand, from the Java program perspective, optimize at the code level.
Recently, has done some in the Java Program Aspect Memory optimization practice, has accumulated some experiences, summarizes as follows:
-
For objects that consume large resources (such as database connections, streams, large collection, and so on), and consider exceptions
In this case, it is not necessary to release obj because the GC will automatically reclaim resources after the Func is executed
public void Func () {
Object obj =new object ();
...
obj=null;
}
But for this kind of operation it is necessary to release early, especially some connection resources, large memory objects such as
public void Func () {
Object obj =new object ();
...
obj=null;
xxxx;//time-consuming operation
}
and for the database resource/stream, when released, consider the occurrence of exception, It is recommended to release the connection in Finalize,
public static Properties loadProperties (String fileName) throws IOException {
FileInputStream stream = new FileInputStream (fileName);
try {
Properties props = new properties (); nbsp
Props.load (stream);
return props;
}
finally {
Stream.Close ();
}
}
-
Optimization logic to avoid the creation of unnecessary objects and to use local variable as much as possible;
because local variables are allocated on the stack, the speed is fast, and the life cycle is fixed, while the logic of the program can be optimized to avoid unnecessary creation of logic, such as
A A = new A ();
if (i==1) {list.add (A);}
The should be changed to
if (i==1) {
A = new A ();
List.add (A);
}
and, for example:
FileInputStream stream = new FileInputStream (fileName);
if (XXX) {
return;
}
stream.xxx;
should be changed to:
if (XXX) {
return;
}
FileInputStream stream = new FileInputStream (fileName);
Stream.xxx;
Optimize the loop logic to reduce the creation and invocation of objects in the loop logic
for (int i = 0; i < xxx.size (); i++) {
Xxx
}
This xxx.size () is called multiple times and is less efficient and can be used:
for (int i = 0, Len = xxx.size (); i < Len; i++) {
Xxx
}
It is also prudent to create objects in the loop, such as
for (int i = 0; i <; ++i) {
Map MyMap = new hashmap<> ();
mymap.xxx;
}
should be changed into
Map MyMap = new hashmap<> ();
for (int i = 0; i <; ++i) {
Mymap.clear ();
Mymap.xxx ();
}
overriding object types with base types
For example, using int instead of Integer,long instead of long, arrays instead of vectors, etc., reduce object creation. In addition, the basic types are stored on the stack and are efficiently created and used.
Replacing multiple string objects with StringBuffer and StringBuilder
Because the string object is fixed-length, any change to the string causes a new string object to be created. So you can use Stringbuferr or StringBuilder instead of string objects at the right time, single-threaded using StringBuilder, stringbuffer in multithreaded situations.
Allocate StringBuffer, arrays, array,vector and other capacities in advance
For objects that need to be allocated continuously, it is better to allocate the capacity ahead of time, generally the default initial capacity is relatively small, such as the capacity of StringBuffer is only 16, if the default capacity is easy to reallocate after the full capacity of a large resource, the cost of memory. So you can avoid this situation by allocating resources in advance.
Caches objects and data that are often used
For objects and data that you often need to use, you can save them with cache (such as shared memory in memory, or remote cache server such as redis,memcached), reducing the cost of duplicate creation of some objects
Use exception with caution
When creating an exception, you need to collect a stack track, a stack trace that describes where the exception was created. Building these stack traces requires a snapshot of the runtime stack, which is a very expensive part. It is therefore prudent to use exceptions, in general, the exception is only the exception that is currently not processed to the upper layer, otherwise you can use the function return value (bool false,object=null) to render the result upward.
When copying an array, use the system.arraycopy () command.
The Arraycopy command is much faster than a cyclic copy array
Java Memory optimization Practices