JAVA 性能调优

  • 格式:pdf
  • 大小:194.79 KB
  • 文档页数:7
如:循环里面的计算,看下例 for(int i=0; terminal=x.length;i<terminal;i++){x = x/scaleA *scaleB;}
应该该成: Double scale = scaleB*scaleA;for(int i=0; terminal=x.length;i<terminal;i++){x = x/scale ;} 4、 避免循环里面进行数据库操作 5、 避免循环里面进行文件读写操作 6、 避免循环出现死循环操作 7、 不要再循环里面使用 try{}catch{} 8、 循环里面不要是使用创建对象块 如: for(int i=1;i<=domainCount;i++) {
五、关于循环的注意点
循环式是影响性能一个大点,需要谨慎使用,注意以下几点: 1、 在重要的循环里,消除循环终止判断时的方法调用。
例如:将 for(int i=0; i<collection.size();i++){ ... }
替换为… 尽量减少对变量的重复计算
for(int i=0; n=collection.size();i<n;i++){...} 2、 通常把大循环放在里面,把小循环放在外面 3、 通常,把与循环 index 不相关的移到循环的外面
对于一些类(如:String 类)来讲,宁愿在重新生成一个新的对象实例,而不应该修改
已经生成的对象实例。 例: String name="Huang"; name="Wei"; name="Feng"; 上述代码生成了三个 String 类型的对象实例。而前两个马上就需要系统进行垃圾回 收处理。如果要对字符串进行连接的操作,性能将得更差,因为系统将不得为此生 成更多得临时变量, 3、 生成对象时,要分配给它合理的空间和大小 JAVA 中的很多类都有它的默认的空间 分配大小。对于 StringBuffer 类来讲,默认的分配空间大小是 16 个字符。如果在程 序中使用 StringBuffer 的空间大小不是 16 个字符,那么就必须进行正确的初始化。 4、 避免生成不太使用或生命周期短的对象或变量。对于这种情况,因该定义一个对象 缓冲池。因为管理一个对象缓冲池的开销要比频繁的生成和回收对象的开销小的多。 5、 只在对象作用范围内进行初始化。JAVA 允许在代码的任何地方定义和初始化对象。 这样,就可以只在对象作用的范围内进行初始化。从而节约系统的开销。 6、 用 new 关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用,所 以不建议使用 new 创建对象。如: 但如果一个对象实现了 Cloneable 接口,我们可以调用它的 clone()方法。clone()方 法不会调用任何类构造函数。在使用设计模式(Design Pattern)的场合,如果用 Factory 模式创建对象,则改用 clone()方法创建新的对象实例非常简单。
例如,下面是 Factory 模式的一个典型实现: public static Credit getNewCredit() { return new Credit(); } 优化后: private static Credit BaseCredit = new Credit(); public static Credit
(3) 当需序列化时使用 transient 当序列化一个类或对象时,对于那些原子类型(atomic)或可以重建的原素要表识为 transient 类型。这样就不用每一次都进行序列化。如果这些序列化的对象要在网络上传 输,这一小小的改变对性能会有很大的提高。
(4) 使用高速缓存(Cache) 对于那些经常要使用而又不大变化的对象或数据,可以把它存储在高速缓存中。这样就 可以提高访问的速度。这一点对于从数据库中返回的结果集尤其重要。
AuditResult auditResult = new AuditResult(); } 这种做法会在内存中保存 N 份这个对象的引用//会浪费大量的内存空间,改为 AuditResult auditResult; for(int i=1;i<=domainCount;i++) {
auditResult=new AuditResult(); } 9、 在重要的循环里使用基本数据类型(int 型数据通常比 long/double 型数据更快) 10、 循环数据过大时,需要变更终止条件,如下: for(int I=0; I< v.size(); I++) { System.out.println( v.get(I).getClass().toString()); } 改为 int size = v.size(); for(int I=0; I<size; I++) { System.out.println( v.get(I).getClass().toString()); }
5、 使编译器和运行时最优化,将几个方法调用放在一个 try/catch 块中,而不是为每 个方法调用实现几个 try/catch 块
6、
三、线程(Threading)
一个高性能的应用程序中一般都会用到线程。因为线程能充分利用系统的资源。在其他 线程因为等待硬盘或网络读写而 时,程序能继续处理和运行。但是对线程运用不当,也会 影响程序的性能。
(5) 使用速度快的 JDBC 驱动器(Driver) JAVA 对访问数据库提供了四种方法。这其中有两种是 JDBC 驱动器。一种是用 JAVA 外 包的本地驱动器;另一种是完全的 JAVA 驱动器。具体要使用哪一种得根据 JAVA 布署的 环境和应用程序本身来定。
(6) 建议使用非阻塞 IO Java 版本较低的 JDK 不支持非阻塞 I/O API。为避免 I/O 阻塞,一些应用采用了创建大 量线程的办法(在较好的情况下,会使用一个缓冲池)。这种技术可以在许多必须支持并 发 I/O 流的应用中见到,如 Web 服务器、报价和拍卖应用等。然而,创建 Java 线程需 要相当可观的开销。 JDK 1.4 引入了非阻塞的 I/O 库(java.nio)。如果应用要求使用版本较早的 JDK,在这 里有一个支持非阻塞 I/O 的软件包。
因此再 java 代码中,如果要用到变长的字符变量时,应该使用 StringBuffer 代替 String append 代替+号 如: String name = new String(“xiao wang”); System.out.println(name+"is my name"); 应该改为: StringBuffer name=new StringBuffer("xiao wang"); System.out.println(name.append("is my name.").toString()); 注意: 1、 消除字符串连接 2、 预分配 StringBuffer 空间 3、StringBuffer 和 StringBuilder 的区别:
getNewCredit() { return (Credit) BaseCredit.clone();} 7、不重复初始化变量
默认情况下,调用类的构造函数时, Java 会把变量初始化成确定的值:所有的对 象被设置成 null,整数变量(byte、short、int、long)设置成 0,float 和 double 变量设置成 0.0,逻辑值设置成 false。
如:线程同步、异步已经多线程的使用,避免死锁,等待超时等问题。 如:正确使用 Vector 类 Vector 主要用来保存各种类型的对象(包括相同类型和不同类型的对象)。但是在一些 情况下使用会给程序带来性能上的影响。这主要是由 Vector 类的两个特点所决定的。 第一,Vector 提供了线程的安全保护功能。即使 Vector 类中的许多方法同步。但是如果 你已经确认你的应用程序是单线程,这些方法的同步就完全不必要了。第二,在 Vector 查找存储的各种对象时,常常要花很多的时间进行类型的匹配。而当这些对象都是同一 类型时,这些匹配就完全不必要了。因此,有必要设计一个单线程的,保存特定类型对 象的类或集合来替代 Vector 类.用来替换的程序如下(StringVector.java):
的同步方法时,会发生”死锁”。即使这两个方法并不共享任何资源。为了避免这个问 题,可以对一个对象实行”多锁”的机制。
四、输入和输出(I/O)
输入和输出包括很多方面,但涉及最多的是对硬盘,网络或数据库的读写操作。对于读 写操作,又分为有缓存和没有缓存的;对于数据库的操作,又可以有多种类型的 JDBC 驱动 器可以选择。但无论怎样,都会给程序的性能带来影响。因此,需要注意如下几点:
4、 抛出异常首先要创建一个新的对象 Throwable 接口的构造函数调用名为 fillInStackTrace()的本地(Native)方法, fillInStackTrace()方法检查堆栈,收集调用跟踪信息。 只要有异常被抛出,VM 就必须调整调用堆栈,因为在处理过程中创建了一个新的对 象。异常只能用于错误处理,不应该用来控制程序流程。
作者 付国杰
创建日期 2012-7-6
Hale Waihona Puke 备注 整理的资料,如有疑问,联系 QQ:369870890
JAVA 性能调优
一、对象的生成和大小的调整
JAVA 程序设计中一个普遍的问题就是没有好好的利用 JAVA 语言本身提供的函数,从而 常常会生成大量的对象(或实例)。由于系统不仅要花时间生成对象,以后可能还需花 时间对这些对象进行垃圾回收和处理。因此,生成过多的对象将会给程序的性能带来很 大的影响。
(1) 使用输入输出缓冲 尽可能的多使用缓存。但如果要经常对缓存进行刷新(flush),则建议不要使用缓存。
(2) 输出流(Output Stream)和 Unicode 字符串 当时用 Output Stream 和 Unicode 字符串时,Write 类的开销比较大。因为它要实现 Unicode 到字节(byte)的转换.因此,如果可能的话,在使用 Write 类之前就实现转换或用 OutputStream 类代替 Writer 类来使用。