方法重构与性能优化
来源:百度文库 编辑:神马文学网 时间:2024/05/16 00:02:59
方法重构与性能优化
太长的方法是一种坏味道,重构时要尽量拆分大方法为小方法。昨天学习了JVM的内存管理,发现将大方法切分为小方法还可以提高内存的释放速度,这与JVM的内存管理有关。在方法调用时,JVM会创建一个stack frame,该方法的参数和局部变量都存放在stack中,当方法调用结束时,该方法的stack frame被销毁,所有的局部变量占用内存被释放。
Java代码
private void bigMethod(){
ClassA p1 = new ClassA();
ClassA p2 = new ClassA();
int p3 = 0;
int p4 =1;
//.... some lines for business logic
ClassA p5 = new ClassA();
ClassA p6 = new ClassA();
int p7 = 0;
int p8 =1;
//.... some lines for business logic
}
private void bigMethod(){ClassA p1 = new ClassA();ClassA p2 = new ClassA();int p3 = 0;int p4 =1;//.... some lines for business logicClassA p5 = new ClassA();ClassA p6 = new ClassA();int p7 = 0;int p8 =1;//.... some lines for business logic}
当方法bigMethod()被调用时,JVM会创建8个局部变量,4个为引用类型,4个为原始类型,他们都被分配在方法的stack中。其中引用类型的变量,还有4个对应的对象被创建在heap中。当bigMethod()调用结束后,p1到p8都被销毁,而引用类型变量对应的对象此时还在heap中,由于对象的引用已经销毁,所以这4个对象处于可以被销毁的状态,由gc决定何时销毁。
对bigMethdo重构后,
Java代码
private void bigMethod(){
smallMethod1();
smallMethod2();
}
private void smallMethod1(){
ClassA p1 = new ClassA();
ClassA p2 = new ClassA();
int p3 = 0;
int p4 =1;
//.... some lines for business logic
}
private void smallMethod1(){
ClassA p5 = new ClassA();
ClassA p6 = new ClassA();
int p7 = 0;
int p8 =1;
//.... some lines for business logic
}
private void bigMethod(){smallMethod1();smallMethod2();}private void smallMethod1(){ClassA p1 = new ClassA();ClassA p2 = new ClassA();int p3 = 0;int p4 =1;//.... some lines for business logic}private void smallMethod1(){ClassA p5 = new ClassA();ClassA p6 = new ClassA();int p7 = 0;int p8 =1;//.... some lines for business logic}
这时调用bigMethod()会发生如下事情,1. 调用方法samllMethod1(),JVM会创建4个局部变量,2个为引用类型,2个为原始类型,他们都被分配在方法的stack中。引用类型的变量还有2个对应的对象被创建在heap中。当samllMethod1()调用结束后,p1到p4都被销毁,而引用类型变量对应的对象此时还在heap中,由于对象的引用已经销毁,所以这2个对象处于可以被销毁的状态,由gc决定何时销毁。
2.调用方法samllMethod2(),重复步骤1的内容。
这样与重构前相比,在调用方法samllMethod2()时已经释放了p1到p4,JVM已经回收了这部分内存。而更重要的是,在调用方法samllMethod2()时,在heap中创建的p1,p2对应的对象已经处于可以销毁的状态,这为JVM提前提供了销毁p1,p2的对象的机会。如果此时正好heap中内存不够用了,需要运行gc来销毁对象,那么p1,p2的对象占用的内存就可以被释放。而在未重勾前,在这个时刻p1,p2的对象还有引用,是不能销毁的。最极端的情况是此时此刻heap的内从不够用了,也没有可以销毁的对象,那么就会发生outmemory异常,系统crash。
还有一种情况,就是如果在一个线程方法中调用了wait(),等待某事件发生来唤醒该线程,那么在该线程方法调用可能会很久才会结束,这段时间内该方法内的局部变量都不能销毁。如果该线程永远没有被唤醒那么方法内的局部变量就永远不能销毁,这会造成内存泄露。
通过将大方法重构为小方法可以提前释放内存,可以在某种程度上避免这种情况的发生
太长的方法是一种坏味道,重构时要尽量拆分大方法为小方法。昨天学习了JVM的内存管理,发现将大方法切分为小方法还可以提高内存的释放速度,这与JVM的内存管理有关。在方法调用时,JVM会创建一个stack frame,该方法的参数和局部变量都存放在stack中,当方法调用结束时,该方法的stack frame被销毁,所有的局部变量占用内存被释放。
Java代码
private void bigMethod(){
ClassA p1 = new ClassA();
ClassA p2 = new ClassA();
int p3 = 0;
int p4 =1;
//.... some lines for business logic
ClassA p5 = new ClassA();
ClassA p6 = new ClassA();
int p7 = 0;
int p8 =1;
//.... some lines for business logic
}
private void bigMethod(){ClassA p1 = new ClassA();ClassA p2 = new ClassA();int p3 = 0;int p4 =1;//.... some lines for business logicClassA p5 = new ClassA();ClassA p6 = new ClassA();int p7 = 0;int p8 =1;//.... some lines for business logic}
当方法bigMethod()被调用时,JVM会创建8个局部变量,4个为引用类型,4个为原始类型,他们都被分配在方法的stack中。其中引用类型的变量,还有4个对应的对象被创建在heap中。当bigMethod()调用结束后,p1到p8都被销毁,而引用类型变量对应的对象此时还在heap中,由于对象的引用已经销毁,所以这4个对象处于可以被销毁的状态,由gc决定何时销毁。
对bigMethdo重构后,
Java代码
private void bigMethod(){
smallMethod1();
smallMethod2();
}
private void smallMethod1(){
ClassA p1 = new ClassA();
ClassA p2 = new ClassA();
int p3 = 0;
int p4 =1;
//.... some lines for business logic
}
private void smallMethod1(){
ClassA p5 = new ClassA();
ClassA p6 = new ClassA();
int p7 = 0;
int p8 =1;
//.... some lines for business logic
}
private void bigMethod(){smallMethod1();smallMethod2();}private void smallMethod1(){ClassA p1 = new ClassA();ClassA p2 = new ClassA();int p3 = 0;int p4 =1;//.... some lines for business logic}private void smallMethod1(){ClassA p5 = new ClassA();ClassA p6 = new ClassA();int p7 = 0;int p8 =1;//.... some lines for business logic}
这时调用bigMethod()会发生如下事情,1. 调用方法samllMethod1(),JVM会创建4个局部变量,2个为引用类型,2个为原始类型,他们都被分配在方法的stack中。引用类型的变量还有2个对应的对象被创建在heap中。当samllMethod1()调用结束后,p1到p4都被销毁,而引用类型变量对应的对象此时还在heap中,由于对象的引用已经销毁,所以这2个对象处于可以被销毁的状态,由gc决定何时销毁。
2.调用方法samllMethod2(),重复步骤1的内容。
这样与重构前相比,在调用方法samllMethod2()时已经释放了p1到p4,JVM已经回收了这部分内存。而更重要的是,在调用方法samllMethod2()时,在heap中创建的p1,p2对应的对象已经处于可以销毁的状态,这为JVM提前提供了销毁p1,p2的对象的机会。如果此时正好heap中内存不够用了,需要运行gc来销毁对象,那么p1,p2的对象占用的内存就可以被释放。而在未重勾前,在这个时刻p1,p2的对象还有引用,是不能销毁的。最极端的情况是此时此刻heap的内从不够用了,也没有可以销毁的对象,那么就会发生outmemory异常,系统crash。
还有一种情况,就是如果在一个线程方法中调用了wait(),等待某事件发生来唤醒该线程,那么在该线程方法调用可能会很久才会结束,这段时间内该方法内的局部变量都不能销毁。如果该线程永远没有被唤醒那么方法内的局部变量就永远不能销毁,这会造成内存泄露。
通过将大方法重构为小方法可以提前释放内存,可以在某种程度上避免这种情况的发生
方法重构与性能优化
最优化ASP程序性能的方法
最优化ASP程序性能的方法
高性能网站性能优化与系统架构(ZT)
高性能网站性能优化与系统架构...
从LiveJournal后台发展看大规模网站性能优化方法
从LiveJournal后台发展看大规模网站性能优化方法
.NET中常用的优化性能方法详解
大规模网站性能优化方法-从LiveJournal后台发展看大规模网站性能优化方法 草根IT...
高性能网站性能优化与系统架构(ZT) - oracle_8i的个人空间 - ITPUB个人...
WPF性能优化点
mysql性能优化
Web页面性能优化
tomcat5性能优化
高性能网站性能优化 - 人月 - CSDNBlog
从LiveJournal后台发展看 大型网站系统架构以及性能优化方法
.NET中26个优化性能方法 一起Ext - 中国最大的EXTJS讨论社区 - Power...
java 性能优化技巧集锦
PHP应用程序的性能优化
Java性能优化技巧集锦
Apache 性能最优化分析
优化NTFS 提高计算机性能
DB2 性能优化快速入门
CDMA无线网络优化流程与方法