paulwong

对象池

如果一个B/S的应用,并发量在2000以上时,新建的对象累积会占用大量内存,当超过一定数量的时候,会报内存不够,使用享元模式就可以解决这一问题,也就是建立对象池。现在的方案可以使用Apache Commons Pool

一、基本String对象测试
import org.apache.commons.pool.impl.GenericKeyedObjectPool; 
import org.apache.commons.pool.BaseKeyedPoolableObjectFactory; 

/** 
* Created by IntelliJ IDEA. 

@author leizhimin 2009-10-27 17:46:18 
*/
 
public class Test 
        
public static void main(String[] args) throws Exception 
                
//创建一个对象池 
                GenericKeyedObjectPool pool = new GenericKeyedObjectPool(new BaseKeyedPoolableObjectFactory() 
                        @Override 
                        
public Object makeObject(Object o) throws Exception 
                                
return o; 
                        }
 
                }
); 

                
//添加对象到池,重复的不会重复入池 
                pool.addObject("a"); 
                pool.addObject(
"a"); 
                pool.addObject(
"b"); 
                pool.addObject(
"x"); 

                
//清除最早的对象 
                pool.clearOldest(); 

                
//获取并输出对象 
                System.out.println(pool.borrowObject("a")); 
                System.out.println(pool.borrowObject(
"b")); 
                System.out.println(pool.borrowObject(
"c")); 
                System.out.println(pool.borrowObject(
"c")); 
                System.out.println(pool.borrowObject(
"a")); 

                
//输出池状态 
                System.out.println(pool.getMaxIdle()); 
                System.out.println(pool.getMaxActive()); 

        }
 
}

输出结果:
a
b
c
c
a
8
8

Process finished with exit code 0

二、自定义复杂对象测试

import org.apache.commons.pool.impl.GenericKeyedObjectPool; 
import org.apache.commons.pool.BaseKeyedPoolableObjectFactory; 

/** 
* Created by IntelliJ IDEA. 

@author leizhimin 2009-10-27 17:46:18 
*/
 
public class Test 
        
public static void main(String[] args) throws Exception 
                
//创建一个对象池 
                GenericKeyedObjectPool pool = new GenericKeyedObjectPool(new BaseKeyedPoolableObjectFactory() 
                        @Override 
                        
public Object makeObject(Object o) throws Exception 
                                
if (o != null && o instanceof User) 
                                        
return o; 
                                
else 
                                        
return null
                        }
 
                }
); 

                
//添加对象到池,重复的不会重复入池 
                pool.addObject("a"); 
                pool.addObject(
"b"); 
                pool.addObject(
"x"); 
                pool.addObject(
null); 
                pool.addObject(
null); 
                pool.addObject(
null); 
                pool.addObject(
new User("zhangsan""123")); 
                pool.addObject(
new User("lisi""112")); 
                pool.addObject(
new User("lisi""112"32)); 
                pool.addObject(
new User("lisi""112"32"一个烂人!")); 


                
//清除最早的对象 
                pool.clearOldest(); 

                
//获取并输出对象 
                User u1 = new User("lisi""112"32"一个烂人!"); 
                System.out.println(pool.borrowObject(u1)); 
                pool.returnObject(u1,u1); 

                
//获取并输出对象 
                User u2 = new User("lisi""112"32"一个烂人!"); 
                System.out.println(pool.borrowObject(u2)); 
                pool.returnObject(u2,u2); 

                
//获取并输出对象 
                User u3 = new User("lisi""112"32); 
                System.out.println(pool.borrowObject(u3)); 
                pool.returnObject(u3,u3); 

                
//获取并输出对象 
                User u4 = new User("lisi""112"); 
                System.out.println(pool.borrowObject(u4)); 
                pool.returnObject(u4,u4); 

                System.out.println(pool.borrowObject(u4)); 
                pool.returnObject(u4,u4); 
                System.out.println(pool.borrowObject(u4)); 
                pool.returnObject(u4,u4); 
                System.out.println(pool.borrowObject(u4)); 
                pool.returnObject(u4,u4); 
                System.out.println(pool.borrowObject(u4)); 
                pool.returnObject(u4,u4); 
                System.out.println(pool.borrowObject(u4)); 
                pool.returnObject(u4,u4); 
                System.out.println(pool.borrowObject(u4)); 
                pool.returnObject(u4,u4); 
                System.out.println(pool.borrowObject(u4)); 
                pool.returnObject(u4,u4); 





                System.out.println(pool.borrowObject(
new User("lisi""112"))); 
//                System.out.println(pool.borrowObject(new User("lisi", "112"))); 

                
//输出池状态 
                System.out.println(pool.getMaxIdle()); 
                System.out.println(pool.getMaxActive()); 
                pool.clearOldest(); 
                pool.close(); 

        }
 
}
 

class User 
        
private String name; 
        
private String pswd; 
        
private int age; 
        
private String reamark; 

        User() 

        }
 

        User(String name, String pswd) 

                
this.name = name; 
                
this.pswd = pswd; 
        }
 

        User(String name, String pswd, 
int age) 
                
this.name = name; 
                
this.pswd = pswd; 
                
this.age = age; 
        }
 

        User(String name, String pswd, 
int age, String reamark) 
                
this.name = name; 
                
this.pswd = pswd; 
                
this.age = age; 
                
this.reamark = reamark; 
        }
 

        
public String getName() 
                
return name; 
        }
 

        
public void setName(String name) 
                
this.name = name; 
        }
 

        
public String getPswd() 
                
return pswd; 
        }
 

        
public void setPswd(String pswd) 
                
this.pswd = pswd; 
        }
 

        
public int getAge() 
                
return age; 
        }
 

        
public void setAge(int age) 
                
this.age = age; 
        }
 

        
public String getReamark() 
                
return reamark; 
        }
 

        
public void setReamark(String reamark) 
                
this.reamark = reamark; 
        }
 

        @Override 
        
public boolean equals(Object o) 
                
if (this == o) return true
                
if (o == null || getClass() != o.getClass()) return false

                User user 
= (User) o; 

                
if (!name.equals(user.name)) return false
                
if (!pswd.equals(user.pswd)) return false

                
return true
        }
 

        @Override 
        
public int hashCode() 
                
int result = name.hashCode(); 
                result 
= 31 * result + pswd.hashCode(); 
                
return result; 
        }
 

        @Override 
        
public String toString() 
                
return "User{" + 
                                
"name='" + name + '\'' + 
             
                   
", pswd='" + pswd + '\'' + 
                                ", age=" + age + 
                                
", reamark='" + reamark + '\'' + 
                                '}'
        }
 
}

测试结果:
User{name='lisi', pswd='112', age=32, reamark='null'}
User{name='lisi', pswd='112', age=32, reamark='一个烂人!'}
User{name='lisi', pswd='112', age=32, reamark='一个烂人!'}
User{name='lisi', pswd='112', age=32, reamark='null'}
User{name='lisi', pswd='112', age=0, reamark='null'}
User{name='lisi', pswd='112', age=0, reamark='null'}
User{name='lisi', pswd='112', age=0, reamark='null'}
User{name='lisi', pswd='112', age=0, reamark='null'}
User{name='lisi', pswd='112', age=0, reamark='null'}
User{name='lisi', pswd='112', age=0, reamark='null'}
User{name='lisi', pswd='112', age=0, reamark='null'}
User{name='lisi', pswd='112', age=0, reamark='null'}
8
8

Process finished with exit code 0

这次测试得出一些有用的结论:
1、复杂对象应该实现equals() 、hashCode()方法,以便不重复入池。
2、对于非入池的目标对象,比如a、b、x字符串,目前没有有效的办法过滤掉,不让其入池,虽然在工厂方法里做了努力。
3、试图将null入池,不会成功的,但也不抛异常。
4、对于池对象,使用应该遵循“接而有还,再借不难”-----从池中获取,不用时候归池,否则当池中没有空闲可用的对象时候,程序会处于等待状态,如果没有显式的调用归还方法,则造成程序死锁。

池的大小是初始化配置的,在没有显式配置指定的情况下,池大小默认为8.可以通过GenericKeyedObjectPool.Config来配置。

posted on 2011-10-23 17:02 paulwong 阅读(330) 评论(0)  编辑  收藏 所属分类: 性能优化


只有注册用户登录后才能发表评论。


网站导航: