Technical Principle and Implementation of Java object pool
Source: Internet
Author: User
■ Object lifecycle analysis in Java
Java object lifecycle consists of three phases: Object creation, object usage, and object clearing. therefore, the object lifecycle can be expressed in the following expression: t = t1 + T2 + T3. T1 indicates the object creation time, and T2 indicates the object usage time, t3 indicates the clearing time. from this, we can see that only T2 is the real effective time, while T1 and T3 are the overhead of the object itself. next let's take a look at the proportion of T1 and t3 in the entire lifecycle of the object.
We know that Java objects are created by constructors. During this process, all constructors in the constructor chain are automatically called. in addition, by default, Java initializes the variable to a definite value when calling the class constructor: all objects are set to null, integer variables (byte, short, Int, long) set to 0, float and double variables to 0.0, and logical values to false. therefore, the time overhead of using the new keyword to create an object is large, as shown in table 1.
Table 1 Comparison of time-consuming operations
Operation | example | standardization time
Local value assignment | I = n | 1.0
Instance assignment | this. I = n | 1.2
Method CALL | funct () | 5.9
New object | new object () | 980
Create an array | new int [10] | 3100
From table 1, we can see that it takes 980 units of time to create an object, which is 980 times of the local value assignment time and 166 times of the method call time, however, it takes more time to create an array.
Let's look at the process of clearing objects. we know that one of the advantages of Java is that Java programmers do not need to explicitly release objects like C/C ++ programmers, but are called garbage collectors) the automatic memory management system automatically recycles the memory occupied by spam objects at a scheduled time or when the memory is insufficient. there are always advantages and disadvantages in everything. Although this provides great convenience for Java programmers, it also brings a large performance overhead. this overhead includes two aspects: object management overhead. GC must monitor the running status of each object in order to release the object correctly, including object application, reference, and reference, assign values. second, when GC starts to recycle "junk" objects, the system will pause the execution of the application, and occupy the CPU alone.
Therefore, to improve the performance of applications, we should minimize the number of times new objects are created. At the same time, we should minimize the time required for T1 and T3, these can be achieved through the object pool technology.
The basic principle of Object pool technology has two core points: caching and sharing. For those frequently used objects, they are cached instead of being released immediately after use, for subsequent applications to reuse, so as to reduce the number of times objects are created and released, and thus improve the application performance. in fact, because the object pool technology limits the number of objects to a certain extent, it also effectively reduces the application memory sales.
Implementing an object pool generally involves the following classes:
1) objectpoolfactory class
This class is mainly used to manage the objectpool of the same type and settings. It generally includes the following two methods:
• Createpool: used to create object pools of specific types and settings;
• Destroypool: Used to release the specified object pool;
To ensure a single instance of objectpoolfactory, the singleton design mode can be used. For details, see the implementation of the getinstance method below:
Public static objectpoolfactory getinstance (){
If (poolfactory = NULL ){
Poolfactory = new objectpoolfactory ();
}
Return poolfactory;
}
2) parameter object (parameterobject) Class
This class is mainly used to encapsulate some attribute parameters of the created Object pool, such as maxcount and mincount.
3) Object pool class
It is used to manage the lending and return of objects to be pooled, and notifies poolableobjectfactory to complete the corresponding work. It generally includes the following two methods:
• GetObject: Used to lend objects from the pool;
• Returnobject: returns pooled objects to the pool and notifies all threads in the waiting state;
4) Pooling object Factory (poolableobjectfactory) Class
This class is mainly responsible for managing the lifecycle of pooled objects. In short, it generally includes Object creation and destruction. Like objectpoolfactory, this class can also be implemented as a single instance.
Implementation of General Object pool
Object pool construction and management can be implemented in multiple ways. the most flexible way is to specify the class type of the pooled object outside the object pool, that is, when the objectpoolfactory class creates an object pool, it dynamically specifies the class type of the object pooled by the object pool, the implementation code is as follows:
...
Public objectpool createpool (parameterobject paraobj, class clstype ){
Return new objectpool (paraobj, clstype );
}
...
The paraobj parameter is used to specify the feature attribute of the Object pool, and the clstype parameter specifies the type of objects stored in the object pool. after an object pool is created, we use it to manage objects. The specific implementation is as follows:
Public class objectpool {
Private parameterobject paraobj; // attribute parameter object of the Object pool
Private class clstype; // type of the objects stored in the object pool
Private int currentnum = 0; // number of currently created objects in the object pool
Private object currentobj; // the objects that can be lent out by the object pool.
Private vector pool; // The pool used to store objects
Public objectpool (parameterobject paraobj, class clstype ){
This. paraobj = paraobj;
This. clstype = clstype;
Pool = new vector ();
}
Public object GetObject (){
If (pool. Size () <= paraobj. getmincount ()){
If (currentnum <= paraobj. getmaxcount ()){
// If no objects are available in the current pool and the number of created objects is smaller than the maximum value
// Poolobjectfactory creates a new object
Poolableobjectfactory objfactory = poolableobjectfactory. getinstance ();
Currentobj = objfactory. Create object (clstype );
Currentnum ++;
} Else {
// If no objects are available in the current pool and the maximum number of created objects has been reached,
// You can only wait for other threads to return objects to the pool.
Synchronized (this ){
Try {
Wait ();
} Catch (interruptedexception e ){
System. Out. println (E. getmessage ());
E. printstacktrace ();
}
Currentobj = pool. firstelement ();
}
}
} Else {
// If there are available objects in the current pool, the objects are taken directly from the pool.
Currentobj = pool. firstelement ();
}
Return currentobj;
}
Public void returnobject (Object OBJ ){
// Ensure that the object has the correct type
If (obj. isinstance (clstype )){
Pool. addelement (OBJ );
Synchronized (this ){
Policyall ();
}
} Else {
Throw new illegalargumentexception ("the object pool cannot store the specified object type ");
}
}
}
From the code above, we can see that objectpool uses a java. util. vector is an extensible Object pool, and its constructor is used to specify the class type of the pooled object and some attributes of the Object pool. when an object is returned to the object pool, it checks whether the object type is correct. when no available object exists in the object pool, it can wait for the used pooled object to return to the pool, or create a new object instance. however, the creation of new object instances is not in the objectpool class, but by the Createobject method of the poolableobjectfactory class. The specific implementation is as follows:
...
Public object Createobject (class clstype ){
Object OBJ = NULL;
Try {
OBJ = clstype. newinstance ();
} Catch (exception e ){
E. printstacktrace ();
}
Return OBJ;
}
...
In this way, even if the implementation of the general object pool is complete, let's take a look at how the client uses it, assuming that the class type of the pooled object is stringbuffer:
...
// Create an object pool Factory
Objectpoolfactory poolfactory = objectpoolfactory. getinstance ();
// Define the attributes of the created Object pool
Parameterobject paraobj = new parameterobject (2, 1 );
// Use the object pool factory to create an object pool for storing stringbuffer objects
Objectpool pool = poolfactory. createpool (paraobj, string buffer. Class );
// Retrieve a stringbuffer object from the pool
Stringbuffer buffer = (stringbuffer) pool. GetObject ();
// Use the stringbuffer object retrieved from the pool
Buffer. append ("hello ");
System. Out. println (buffer. tostring ());
...
It can be seen that the general object pool is very convenient to use, not only can avoid the overhead of frequent object creation, but also a high degree of universality. however, it is a pity that a large number of cast operations and some synchronization operations on the vector class are required to improve the performance in some situations, especially for objects with short creation periods.
■ Implement a dedicated Object pool
Because the management overhead of the general object pool is relatively large, It offsets most of the advantages of reusing objects to some extent. to solve this problem, you can use the dedicated Object pool method. that is, the class type of the object pooled by the object pool is not dynamically specified, but has been specified in advance. in this way, it is easier to implement than the general object pool. Instead of the objectpoolfactory and poolableobjectfactory classes, they can directly integrate their functions into the objectpool class, the details are as follows (assuming that the class type of the pooled object is still stringbuffer, and the place indicated by the ellipsis indicates that the Code is the same as that of the general object pool ):
Public class objectpool {
Private parameterobject paraobj; // attribute parameter object of the Object pool
Private int currentnum = 0; // number of currently created objects in the object pool
Private stringbuffer currentobj; // objects that can be lent out by the object pool currently
Private vector pool; // The pool used to store objects
Public objectpool (parameterobject paraobj ){
This. paraobj = paraobj;
Pool = new vector ();
}
Public stringbuffer GetObject (){
If (pool. Size () <= paraobj. getmincount ()){
If (currentnum <= paraobj. getmaxcount ()){
Currentobj = new stringbuffer ();
Currentnum ++;
}
...
}
Return currentobj;
}
Public void returnobject (Object OBJ ){
// Ensure that the object has the correct type
If (stringbuffer. isinstance (OBJ )){
...
}
}
Conclusion
1. the appropriate use of Object pool technology can effectively improve the performance of applications. currently, Object pool technology has been widely used. For heavyweight objects such as network and database connections, Object pool technology is generally used. note the following when using the object pool technology:
2. object pool technology is not applicable in any situation. basically, the object pool technology is applicable only when repeated object generation is a key factor affecting performance. however, it is not important to improve the performance caused by pooling. It is better not to use the object Pooling technology to keep the code concise.
3. select the implementation method of the Object pool according to the actual situation. if you want to create a public object pool technical implementation package, or you need to dynamically specify the class type of the pooled object in the program, select the general object pool. in most cases, you can use a dedicated Object pool.
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.