QLExpress脚本语言技术讲解(7)-------QlExpress的对象缓存优化

(注:相关代码请参考 com.ql.util.express.instruction.OperateDataCacheManager类,

QLExpress 源代码下载地址:http://code.taobao.org/p/QLExpress/src/ )

 

 

几乎所有的动态脚本语言在运行期都需要频繁的创建对象,并且强烈依赖语言的底层垃圾回收(java中称作GC ,可以参考这篇 《Java GC 》http://bruce-ko.iteye.com/blog/420262 )。

 

在多线程运行的情况下,cpu和内存的消耗很有可能被这个过程消耗殆尽。

近期,QlExpress在这方面做了较大的优化,在实际使用过程中,也确实效果明显。

 

 

本篇将具体介绍QlExpress创建对象过程的优化实现原理,也欢迎广大技术码农共同交流探讨。

 

public class OperateDataCacheManager {
	
	private static ThreadLocal<IOperateDataCache> m_OperateDataObjectCache = 
		new ThreadLocal<IOperateDataCache>(){
		protected IOperateDataCache initialValue() {
	        return new OperateDataCacheImpl(30);
	    }
	};

        //获取ThreadLocal成员变量
	public static IOperateDataCache getOperateDataCache(){
		return m_OperateDataObjectCache.get();
	}

//其他代码逻辑

}
 

ThreadLocal成员变量可以保证多线程情况下数据的独立性、安全性,并且尽量保持高并发性,工作原理可以参考

 《理解ThreadLocal 》 http://blog.csdn.net/qjyong/article/details/2158097

 

 

 


QLExpress脚本语言技术讲解(7)-------QlExpress的对象缓存优化_第1张图片

 

 

具体方案请看上图的数据结构示意图,(点击可以看大图)

 

在原来每次需要

new OperateDataField(Object aFieldObject,String aFieldName)       的时候,

每一次转而调用

OperateDataCacheManager.fetchOperateDataField(Object aFieldObject,String aFieldName),

这个时候会从缓冲区域获取到一个OperateDataField,成员变量被赋值。

而每次脚本运行完资源回收的时候,会把 OperateDataField【0..field】全部显示置为null,使所有的外部链接对象被java虚拟机马上释放。

 

注意:如果超过len长度, fetchOperateDataField 会直接调用new OperateDataField(Object aFieldObject,String aFieldName)返回,回收内存也就只能等jvm定期去gc了。

 

通常,我们的web应用服务器都会使用线程池来作为多线程并发的管理。

常驻内存的线程使用类似qlExpress的内存缓冲区管理方式, 减少频繁对象创建 可以很大程度上的带来的 CPU开销,内存被重复利用,也会稳定很多。

经过优化的方案在我们实际使用中也确实看到了效果,cpu 的load减少了近一倍。

 

 

你可能感兴趣的:(缓存,内存优化)