Java程序性能优化-代理模式(5)代理模式( )
在以上代码中 使用CtField make()方法和CtNewMehod make()方法在运行时生成java代码逻辑优化了代理类java代码逻辑优化的字段和方法 这些逻辑由Javassistjava代码逻辑优化的CtClass对象处理 将Java代码转换为对应的字节码 并生成动态代理类的实例
注意 与静态代理相比 动态代理可以很大幅度地减少代码行数 并提升系统的灵活性
在Java中 动态代理类的生成主要涉及对ClassLoader的使用 这里以CGLIB为例 简要阐述动态类的加载过程 使用CGLIB生成动态代理 首先需要生成Enhancer类实例 并指定用于处理代理业务的回调类 在Enhancer create()方法中 会使用DefaultGeneratorStrategy Generate()方法生成动态代理类的字节码 并保存在byte数组中 接着使用ReflectUtils defineClass()方法 通过反射 调用ClassLoader defineClass()方法 将字节码装载到ClassLoader中 完成类的加载 最后使用ReflectUtils newInstance()方法 通过反射 生成动态类的实例 并返回该实例 无论使用何种方法生成动态代理 虽然实现细节不同 但主要逻辑都如图 所示
图实现动态代理的基本步骤
前文介绍的几种动态代理的生成方法 性能有一定差异 为了能更好地测试它们的性能 去掉DBQuery类中的sleep()代码 并使用以下方法测试
public static final int CIRCLE= ;
public static void main(String[] args) throws Exception {
IDBQuery d=null;
long begin=System currentTimeMillis()
d=createJdkProxy()//测试JDK动态代理
System out println( createJdkProxy:(System currentTimeMillis() begin))
System out println( JdkProxy class:d getClass() getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i)
d request()
System out println( callJdkProxy:(System currentTimeMillis() begin))
begin=System currentTimeMillis()
d=createCglibProxy()//测试CGLIB动态代理
System out println( createCglibProxy:(System currentTimeMillis() begin))
System out println( CglibProxy class:d getClass() getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i)
d request()
System out println( callCglibProxy:(System currentTimeMillis() begin))
begin=System currentTimeMillis()
d=createJavassistDynProxy()//测试Javaassist动态代理
System out println( createJavassistDynProxy:(System currentTimeMillis() begin))
System out println( JavassistDynProxy class:d getClass() getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i)
d request()
System out println( callJavassistDynProxy:(System currentTimeMillis() begin))
begin=System currentTimeMillis()
d=createJavassistBytecodeDynamicProxy()//测试Javassist动态代理
System out println( createJavassistBytecodeDynamicProxy:(System currentTimeMillis() begin))
System out println( JavassistBytecodeDynamicProxy class:d getClass()
getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i)
d request()
System out println( callJavassistBytecodeDynamicProxy:(System currentTimeMillis() begin))
}
返回目录Java程序性能优化 让你的Java程序更快 更稳定
编辑推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
J ME移动开发实战教学视频
Visual C音频/视频技术开发与实战
Oracle索引技术
lishixinzhi/Article/program/Java/gj/201311/27830
Java代码的优化方法有哪些说到代码优化,每个人或多或少都掌握一到两种方法 , 但是这样的方法对提升代码运行效率效果不大,最重要是对代码的重视和了解,这样才能提升代码的运行效率 。在进行代码优化的过程中,方法是非常重要的,多掌握几种方法,根据代码的不同情况选择适合的方法进行优化 。下面电脑培训为大家介绍Java代码优化的几种方法 。
1、使用指定类、方法的final修饰符
具有final修饰符的类不可派生 。在Java核心API中,有许多最终应用程序的例子,例如java.lang.String , 整个类都是final 。为类指定final修饰符允许继承类 , 并且为方法指定final修饰符允许覆盖该方法 。如果将类指定为final,IT培训认为该类的所有方法都是final 。Java编译器将寻找内联所有最终方法的机会 。内联对于提高Java操作的效率非常重要 。这可以将性能平均提高50% 。
2、重用对象
String对象的使用是非常重要的,StringBuilder/StringBuffer并不是字符串连接 。由于Java虚拟机需要时间来生成对象,所以将来垃圾收集和处理这些对象可能需要一些时间 。因此,生成太多对象将对程序的性能产生很大影响 。
3、使用局部变量
调用方法时传递的参数以及在调用中创建的临时变量都保存在堆栈中,速度更快 。其他变量(如静态变量和实例变量)在堆中创建并且速度较慢 。此外 , 昆明北大青鸟发现在堆栈中创建的变量,当方法完成运行时,内容消失 , 不需要进行额外的垃圾收集 。
4、及时关闭流
在Java编程过程中,在执行数据库连接和I/O流操作时要小心 。使用后,北大青鸟云南嘉荟校区官网建议应及时关闭以释放资源 。因为这些大型物体的操作会导致系统的大量开销,稍微粗心会导致严重的后果 。
如何优化JAVA代码及提高执行效率网站优化通常包含两方面的内容:减小代码的体积和提高代码的运行效率 。减小代码的体积已经写过太多这类的文章了,下面就简单讨论下如何提高代码的效率 。一、不用new关键词创建类的实例用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用 。但如果一个对象实现了Cloneable接口,我们可以调用它的clone()方法 。clone()方法不会调用任何类构造函数 。在使用设计模式(DesignPattern)的场合,如果用Factory模式创建对象,则改用clone()方法创建新的对象实例非常简单 。二、使用非阻塞I/O版本较低的JDK不支持非阻塞I/OAPI 。为避免I/O阻塞,一些应用采用了创建大量线程的办法(在较好的情况下,会使用一个缓冲池) 。这种技术可以在许多必须支持并发I/O流的应用中见到,如Web服务器、报价和拍卖应用等 。然而,创建Java线程需要相当可观的开销 。JDK1.4引入了非阻塞的I/O库(java.nio) 。如果应用要求使用版本较早的JDK,需要支持非阻塞I/O的软件包 。三、慎用异常异常对性能不利 。抛出异常首先要创建一个新的对象 。Throwable接口的构造函数调用名为fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法检查堆栈 , 收集调用跟踪信息 。只要有异常被抛出,VM就必须调整调用堆栈,因为在处理过程中创建了一个新的对象 。异常只能用于错误处理,不应该用来控制程序流程 。四、不要重复初始化变量默认情况下 , 调用类的构造函数时 , Java会把变量初始化成确定的值:所有的对象被设置成null,整数变量(byte、short、int、long)设置成0 , float和double变量设置成0.0,逻辑值设置成false 。当一个类从另一个类派生时,这一点尤其应该注意,因为用new关键词创建一个对象时,构造函数链中的所有构造函数都会被自动调用 。五、尽量指定类的final修饰符带有final修饰符的类是不可派生的 。在Java核心API中,有许多应用final的例子,例如java.lang.String 。为String类指定final防止了人们覆盖length()方法 。另外,如果指定一个类为final,则该类所有的方法都是final 。Java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关) 。此举能够使性能平均提高50% 。六、尽量使用局部变量调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快 。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢 。另外,依赖于具体的编译器/JVM,局部变量还可能得到进一步优化,望采纳,谢谢 。
北大青鸟java培训:Java学习中代码优化的方法有哪些?每个人都说代码是程序员手中的一把雕刻刀,是对他们产品轮廓和细节的打磨 。
每个程序员在代码优化方面需要做的是,即使是每天处理代码的程序员也有很多关于他们编写代码的问题 , 所以优化很重要 。
下面山西山西IT培训为大家介绍代码优化的方法 。
1、尽量重用目标特别是,使用代表字符串收敛的String目标应该使用StringBuilder/StringBuffer 。
因为Java虚拟机不仅要花时间生成目标,而且可能还需要花时间检索和删除这些目标,所以山西计算机学院发现生成太多目标会对程序的功能产生重大影响 。
2、可以运用局部变量调用方法时传递的参数和调用中创建的临时变量保存在堆栈中的速度更快 。
其他变量,如静态变量、实例变量等等,在堆中创建,速度较慢 。
此外,山西北大青鸟发现在堆栈中创建的变量 , 方法的操作结束,当这些内容都消失了,就不需要额定废物回收 。
3、及时封闭流Java的程序编写过程中 , 数据库连接,I/O流操作必须谨慎,应用结束后,应该及时关闭发布资源 。
因为山西java培训发现这些大目标的运行会造成大系统支出,稍有不慎就会导致严重的结果 。
Java代码如何优化今天就跟中公优就业一起来看看java代码优化细节 。
1、尽量指定类、方法的final修饰符
带有final修饰符的类是不可派生的 。在Java核心API中,有许多应用final的例子,例如java.lang.String,整个类都是final的 。为类指定final修饰符可以让类不可以被继承 , 为方法指定final修饰符可以让方法不可以被重写 。如果指定了一个类为final,则该类所有的方法都是final的 。Java编译器会寻找机会内联所有的final方法,内联对于提升Java运行效率作用重大,具体参见Java运行期优化 。此举能够使性能平均提高50% 。
2、尽量重用对象
特别是String对象的使用,出现字符串连接时应该使用StringBuilder/StringBuffer代替 。由于Java虚拟机不仅要花时间生成对象,以后可能还需要花时间对这些对象进行垃圾回收和处理 , 因此,生成过多的对象将会给程序的性能带来很大的影响 。
3、尽可能使用局部变量
调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中速度较快,其他变量,如静态变量、实例变量等,都在堆中创建,速度较慢 。另外 , 栈中创建的变量,随着方法的运行结束,这些内容就没了,不需要额外的垃圾回收 。
4、及时关闭流
Java编程过程中,进行数据库连接、I/O流操作时务必小心 , 在使用完毕后,及时关闭以释放资源 。因为对这些大对象的操作会造成系统大的开销,稍有不慎,将会导致严重的后果 。
5、尽量减少对变量的重复计算
明确一个概念,对方法的调用,即使方法中只有一句语句,也是有消耗的,包括创建栈帧、调用方法时保护现场、调用方法完毕时恢复现场等 。所以例如下面的操作:
for (int i = 0; ilist.size(); i){...}
建议替换为:
for (int i = 0, int length = list.size(); ilength; i){...}
这样,在list.size()很大的时候,就减少了很多的消耗
6、尽量采用懒加载的策略,即在需要的时候才创建
例如:
String str = "aaa";if (i == 1){list.add(str);}
建议替换为:
if (i == 1){String str = "aaa";list.add(str);}
7、慎用异常
异常对性能不利 。抛出异常首先要创建一个新的对象,Throwable接口的构造函数调用名为fillInStackTrace()的本地同步方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息 。只要有异常被抛出,Java虚拟机就必须调整调用堆栈,因为在处理过程中创建了一个新的对象 。异常只能用于错误处理 , 不应该用来控制程序流程 。
8、不要在循环中使用try…catch…,应该把其放在最外层
除非不得已 。如果毫无理由地这么写了,只要你的领导资深一点、有强迫症一点,八成就要骂你为什么写出这种垃圾代码来了
9、如果能估计到待添加的内容长度,为底层以数组方式实现的集合、工具类指定初始长度
比如ArrayList、LinkedLlist、StringBuilder、StringBuffer、HashMap、HashSet等等,以StringBuilder为例:
(1)StringBuilder() // 默认分配16个字符的空间
(2)StringBuilder(int size) // 默认分配size个字符的空间
(3)StringBuilder(String str) // 默认分配16个字符 str.length()个字符空间
可以通过类(这里指的不仅仅是上面的StringBuilder)的来设定它的初始化容量,这样可以明显地提升性能 。比如StringBuilder吧,length表示当前的StringBuilder能保持的字符数量 。因为当StringBuilder达到最大容量的时候,它会将自身容量增加到当前的2倍再加2 , 无论何时只要StringBuilder达到它的最大容量 , 它就不得不创建一个新的字符数组然后将旧的字符数组内容拷贝到新字符数组中—-这是十分耗费性能的一个操作 。试想,如果能预估到字符数组中大概要存放5000个字符而不指定长度,最接近5000的2次幂是4096,每次扩容加的2不管,那么:
(1)在4096 的基础上 , 再申请8194个大小的字符数组,加起来相当于一次申请了12290个大小的字符数组,如果一开始能指定5000个大小的字符数组,就节省了一倍以上的空间
(2)把原来的4096个字符拷贝到新的的字符数组中去
这样,既浪费内存空间又降低代码运行效率 。所以,给底层以数组实现的集合、工具类设置一个合理的初始化容量是错不了的,这会带来立竿见影的效果 。但是 , 注意,像HashMap这种是以数组 链表实现的集合,别把初始大小和你估计的大小设置得一样 , 因为一个table上只连接一个对象的可能性几乎为0 。初始大小建议设置为2的N次幂,如果能估计到有2000个元素,设置成new HashMap(128)、new HashMap(256)都可以 。
10、当复制大量数据时,使用System.arraycopy()命令
【java代码逻辑优化 java代码优化遵循的原则有哪些】java代码逻辑优化的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java代码优化遵循的原则有哪些、java代码逻辑优化的信息别忘了在本站进行查找喔 。
推荐阅读
- 广州微信购物小程序搭建,微信小程序做购物网站
- 策略经营末日生存类游戏,末日生存经营类手游
- 腾讯前几年下架的格斗游戏,腾讯出的格斗游戏叫什么
- c语言水仙花数函数专题 c语言上机报告之水仙花数
- js实现计算一个月还剩多少天,js计算当年剩余时间
- css3最佳工具,css工具箱
- 印度网红上海直播卖车,印度土豪来上海傻眼了
- go语言如何输入一个数组 go语言获取键盘输入
- js声明对象动态添加属性,js动态在对象中添加字段