`

方法重构与性能优化

阅读更多
  太长的方法是一种坏味道,重构时要尽量拆分大方法为小方法。昨天学习了JVM的内存管理,发现将大方法切分为小方法还可以提高内存的释放速度,这与JVM的内存管理有关。在方法调用时,JVM会创建一个stack frame,该方法的参数和局部变量都存放在stack中,当方法调用结束时,该方法的stack frame被销毁,所有的局部变量占用内存被释放。
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
}

当方法bigMethod()被调用时,JVM会创建8个局部变量,4个为引用类型,4个为原始类型,他们都被分配在方法的stack中。其中引用类型的变量,还有4个对应的对象被创建在heap中。当bigMethod()调用结束后,p1到p8都被销毁,而引用类型变量对应的对象此时还在heap中,由于对象的引用已经销毁,所以这4个对象处于可以被销毁的状态,由gc决定何时销毁。
对bigMethdo重构后,
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(),等待某事件发生来唤醒该线程,那么在该线程方法调用可能会很久才会结束,这段时间内该方法内的局部变量都不能销毁。如果该线程永远没有被唤醒那么方法内的局部变量就永远不能销毁,这会造成内存泄露。
通过将大方法重构为小方法可以提前释放内存,可以在某种程度上避免这种情况的发生。
分享到:
评论
15 楼 zhuxing 2009-03-24  
taupo 写道
按照楼主的说法,我还可以说,JVM会生成一个方法列表【数组】,方法越多该列表就越大,调用的时候查找就越慢,更占用内存,性能就下降了哦

当然这些都是很微小的影响,理论上可能对性能有影响,但是这点影响你是否能感觉到呢?
所以我觉得对性能是否真正有提升,很难说
我觉得重构方法的主要作用还是在于重用和便于阅读理解


赞同taupo说的

方法大会导致过多的临时变量占用栈内存,那调用层次、调用上下文信息就不会???
一般我们遇到stack over flow的时候,大部分是调用层次引起的问题吧,例如死循环^_^

还有:觉得楼主对性能过于敏感了^_^ 
14 楼 danni505 2009-03-05  
谢谢楼上的提点,是的,我也思考了这个问题的使用场景,觉得这个如果从系统层面来看可能难以集中解决,不过对于一个大的模块则可以采用组合方式,继承我觉得不易控制,不赞同使用,比如一个系统的所有报表则可以进行一些集中定义,然后在各个报表实现中调用。这样的话对于所对公共逻辑的定义则显得十分重要,因为这必然会产生高耦合的情况,所以个人觉得正如楼上所说这种设计改良只适用于局部设计。
有不同观点者请跟帖。
13 楼 javavsnet 2009-03-05  
danni505 写道
最近也在思考这个问题:
    我们用的是BS结构的MVC开发模式,“业务层+Dao层”的模式,某个模块的一个httpRequest过来就把请求定位到该模块的业务层,然后调DAO层操作数据,然后处理结果返回给浏览器端。
    这样有一个问题出现了,当模块逐渐增多的时候,我们的业务、Dao操作就会出现一些重复,或者说是相类似的情况,那么作为整个系统来说,这些是可以通过改善设计而瘦身的,可是到目前为止我还没有找到一个比较好的解决方法?希望各位同仁能说说你们是怎么面对这个问题的,谢谢。

你的问题没有具体情况是无法回答的。通常对重复的代码有两种方式来重构,1是继承,把公共的逻辑提出放到父类中 2是组合,把公共的逻辑提出放到单独类中,其他类引用这个类。两种方式各有适用场景。
12 楼 danni505 2009-03-05  
最近也在思考这个问题:
    我们用的是BS结构的MVC开发模式,“业务层+Dao层”的模式,某个模块的一个httpRequest过来就把请求定位到该模块的业务层,然后调DAO层操作数据,然后处理结果返回给浏览器端。
    这样有一个问题出现了,当模块逐渐增多的时候,我们的业务、Dao操作就会出现一些重复,或者说是相类似的情况,那么作为整个系统来说,这些是可以通过改善设计而瘦身的,可是到目前为止我还没有找到一个比较好的解决方法?希望各位同仁能说说你们是怎么面对这个问题的,谢谢。
11 楼 tinyyea 2009-03-04  
ftuo 写道
感觉还有一个好处就是容易代码阅读。

TaoistWar 写道
还有个好处可以复用


可以复用倒是真的,
容易阅读倒是仁者见仁,看你给方法命名的水平了,名字取得太丑的你还得F3来看看代码,然后又跳回去反而复杂了。
10 楼 wzywjy 2009-03-04  
频繁的gc也不好把,重构的首要目的应该还是复用,减少代码的重复
9 楼 xiejin2008 2009-03-04  
楼主讲起来,看起来蛮有道理的。可不可以让我们看看具体测试数字的体现呢。重构方法。当然蛮好的。思路更加清晰嘛。
8 楼 val831201 2009-03-03  
这个方法的拆分,应该主要考虑逻辑吧,即一个长方法里实现了几个小功能,分成小方法来实现,会使程序更清晰
7 楼 sharp_lover 2009-02-20  
如果将一个长的方法拆分成好几个小的方法,在调用的时候会显得麻烦。
6 楼 taupo 2009-02-19  
按照楼主的说法,我还可以说,JVM会生成一个方法列表【数组】,方法越多该列表就越大,调用的时候查找就越慢,更占用内存,性能就下降了哦

当然这些都是很微小的影响,理论上可能对性能有影响,但是这点影响你是否能感觉到呢?
所以我觉得对性能是否真正有提升,很难说
我觉得重构方法的主要作用还是在于重用和便于阅读理解
5 楼 luckaway 2009-02-19  
方法调用也要消耗资源的!

能优化性能---这个要拿测试数据出来了!



4 楼 TaoistWar 2009-02-17  
还有个好处可以复用
3 楼 ftuo 2009-02-17  
感觉还有一个好处就是容易代码阅读。
2 楼 gbb21 2009-01-10  
减少使用长方法的主要目的并不是加速内存回收吧?
1 楼 LookAtPic 2009-01-09  
值得学习,我想请问一下,如何学习JVM的?本人菜鸟,有没有相关方面的资料!

相关推荐

    软件工程中的代码重构与性能优化.pptx

    ### 软件工程中的代码重构与性能优化 #### 第一章:简介 **代码重构与性能优化概述** - **代码重构**:是指在不改变软件外部行为的前提下,对内部结构进行调整,以提高代码质量的过程。这通常涉及到对代码结构的...

    软件工程中的代码重构与性能优化方法研究.pptx

    ### 软件工程中的代码重构与性能优化方法研究 #### 第一章:软件工程概述 **软件工程简介** 软件工程是一门集成了系统化、规范化的原理与方法的学科,旨在有效地进行软件产品的开发、运行及维护。自20世纪50年代...

    软件工程中的代码重构与性能优化方法.pptx

    ### 软件工程中的代码重构与性能优化方法 #### 第1章 软件工程概述 **软件工程概念** - **定义**:软件工程是一门应用计算机科学、数学及管理科学等原理,以系统化、规范化、可度量化的方法进行软件的开发、运行...

    前端重构实践(一):性能优化

    前端重构实践(一):性能优化 前端重构实践是指对前端代码进行重构以提高性能和模块化。性能优化是前端开发中非常重要的一部分,因为页面加载速度对用户体验和搜索引擎优化都有着极高的要求。本文将讨论如何对前端...

    人民邮电(图灵)-CSS重构:样式表性能调优

    人民邮电(图灵)-CSS重构:样式表性能调优.201711.epub 人民邮电(图灵)-CSS重构:样式表性能调优

    可重构平台下AES算法的流水线性能优化

    本文在可重构平台上针对128位密钥长度AES算法的流水线性能优化技术进行了研究,通过对基本运算优化、循环展开、轮内流水线、轮间流水线、混合多级流水线结构优化等方法的讨论和实现,对比不同优化方法的优缺点及适用...

    数据库性能优化方案

    数据库性能优化是IT领域中的一个核心议题,尤其对于...文件“数据库性能优化方案.htm”和“数据库性能优化方案.files”可能包含更具体的实例和工具使用指南,学习和实践这些资料将有助于提升数据库管理与优化的能力。

    ORACLE DATABASE 11G性能优化攻略_高清_美 Sam R Alapati.pdf

    ### 三、性能优化的主要方法 #### 3.1 SQL查询优化 SQL查询是数据库中最常见的操作之一,其执行效率直接影响到应用程序的整体性能。优化SQL查询的方法包括: - **索引优化**:合理地创建和使用索引可以显著提高...

    ORACLE-性能优化技术内幕

    《ORACLE-性能优化技术内幕》是一本深入探讨Oracle数据库性能优化的专业书籍,它涵盖了大量实用的方法和技术,旨在帮助数据库管理员和开发人员提升系统效率,降低运行成本。Oracle数据库是全球广泛使用的数据库管理...

    Oracle Database 性能调整与优化 系列书.rar

    "Oracle Database 11gR2性能调整与优化"与"Oracle Database 12cR2性能调整与优化"这两本书分别针对Oracle的不同版本,提供了深入的性能优化策略和技巧。 Oracle Database 11gR2性能调整主要涉及以下几个方面: 1. ...

    Oracle 数据库性能优化与运维最佳实践

    "Oracle数据库性能优化与运维最佳实践"的主题涵盖了如何确保Oracle数据库高效、稳定运行的关键技术和策略。 首先,性能优化涉及多个层面,包括SQL查询优化、存储结构优化、索引设计以及数据库参数调整。SQL查询优化...

    Java程序性能优化 让你的Java程序更快、更稳定pdf文档视频资源

    除此之外,重构也是性能优化的一个重要环节。重构是为了改善代码的结构和可读性,而不改变其外在行为。良好的代码结构可以使得后续的优化更容易进行,同时也能避免因为代码混乱导致的性能问题。 总结来说,这个资源...

    java程序性能优化

    Java程序性能优化是Java开发中的重要环节,它旨在提高应用程序的运行效率,减少资源消耗,提升用户体验。在Java世界中,性能优化涵盖了多个层面,包括代码优化、内存管理、线程调度、数据库交互以及JVM参数调整等。...

    ORACLE19c数据库性能优化说明.docx

    总结来说,Oracle 19c的性能优化涉及了优化器选择、索引设计与管理等多个层面。通过理解这些原则,我们可以更有效地调整SQL语句,优化索引,从而提升数据库的整体性能。在实际操作中,还应注意监控数据库性能,根据...

    重构与模式2.pdf

    - **模式与重构的联系**:书中深入讨论了模式和重构之间的联系,包括如何利用重构来优化设计、提高代码质量和适应性。 #### 四、重构与模式的应用场景 - **维护现有系统**:对于已经存在的系统,可以通过重构引入...

    Oracle企业DBA性能优化

    Oracle企业DBA(Database Administrator)性能优化是数据库管理领域中的核心任务,对于保障系统的高效运行至关重要。Oracle数据库作为全球广泛使用的数据库系统,其性能优化涉及多个层面,包括SQL查询优化、存储优化...

    SQLSERVER性能优化综述

    SQLSERVER性能优化综述 ...总之,SQLSERVER的性能优化涵盖了系统设计、开发、运维等多个环节,需要全面考虑业务需求、数据模型、数据库架构和硬件资源,通过科学的方法和策略,实现系统性能的最大化。

    遗留系统重构与维护

    1. 性能优化:随着系统运行时间的增长,性能问题可能会逐渐显现,需要对数据库查询、文件IO、算法效率等方面进行优化。 2. 安全性修复:对系统进行安全漏洞扫描和修复,增强系统的安全防护能力。 3. 功能扩展:根据...

Global site tag (gtag.js) - Google Analytics