Java性能调优续

标签: java 性能调优 | 发表时间:2014-03-17 08:34 | 作者:细雨纷纷欲断魂
出处:http://www.iteye.com

Java性能调优续

3.2 字符串的调优
       下面列出一些常见的关于字符串优化的策略,简单的我就不多作解释了。

1) 使用规则表达式处理字符串匹配代替复杂的字符串查找和复制操作;

2) 使用不拷贝字符串中字符的高效方法,例如String.subString()方法;

3) 尽可能不要使用需要拷贝字符串中字符的低效方法,例如String.toUpperCase()和String.toLowercase();

4) 在编译期使用String的“+”操作符来执行连接操作,在运行期使用StringBuffer执行连接操作;

这里特别强调一下,因为我已经在网上看到好多文章都推荐使用StringBuffer的append()方法来做字符串的连接操作。其实在JVM能够在编译期就能确定结果的情形,使用String的“+”操作符的性能要好很多。

3.3 异常,类型转换和变量
       1) 考虑在抛出异常的时候是否可以不即时生成堆栈信息而使用一个已有的异常实例;

       创建异常的开销很大。当创建一个异常时,需要收集一个栈跟踪(Stack Trace),这个栈跟踪用于描述异常是在何处创建的。构建这些栈跟踪时需要为运行时栈做一份快照,正是这一部分开销很大。运行时栈不是为有效的异常创建 而设计的,而是设计用来让运行时尽可能快地运行。入栈,出栈,入栈,出栈。让这样的工作顺利完成,而没有任何不必要的延迟。但是,当需要创建一个 Exception时,JVM不得不说:“先别动,我想就你现在的样子存一份快照,所以按时停止入栈和出栈操作,笑着等我拍完快照吧。”栈跟踪不只包含运 行时栈中的一两个元素,而是包含这个栈中的每一个元素,从栈顶到栈底,还有行号和一切应有的东西。

       因此,创建异常这一部分开销很大。从技术上讲,栈跟踪快照是在本地方法Throwable.fillInStackTrace()中发生的,这个方法不是 从Throwable contructor那里调用的。但是这并并没有什么影响——如果你创建了一个Exception,就得付出代价。好在捕获异常开销不大,因此可以用 try-catch将核心内容包起来。你也可以在方法定义中定义throws子句,这样对性能不会造成什么损失。从技术上讲,你甚至可以随意地抛出异常, 而不用花费很大的代价。招致性能损失的并不是throw操作——尽管在没有预先创建异常的情况下就抛出异常是有点不寻常。真正要花代价的是创建异常。

       幸运的是,好的编程习惯已教会我们,不应该不管三七二十一就抛出异常。异常是为异常的情况而设计的,使用时也应该牢记这一原则。但是,万一你不想遵从好的编程习惯,Java语言就会让你知道,那样就可以让你的程序运行的更快,从而鼓励你去那样做。

       2) 用instanceof替代在try-catch中做投机的强制类型转换方法;

       3) 尽可能少的使用强制类型转换方法,尤其是使用类型特定的集合类时;

       4) 使用int优先于其他所有的数据类型;

       5) 尽可能使用基本数据类型做临时变量;

       6) 考虑直接获取实例变量而不通过get,set方法获取(注意:这不符合面向对象的封装原则,不推荐使用)。

3.4 循环,选择和递归
       1) 在循环中消除不必要的代码,做尽可能少的事情;

       2) Switch语句中使用连续的case值;

       3) 确定是否真的需要用到递归,最好转为用循环来实现。

3.5 输入输出操作
       1) 在程序中尽量不要使用System.out这样的语句,而使用log4j这样的日志工具替换,以在程序正式上线的时候可以关闭所有不必要的日志操作提高性能;

       2) 当程序中有大量的I/O操作时,考虑将日志写入不同的文件做到并行化操作以提高性能,并可以用一个后台线程执行I/O操作而不打断正常程序的执行;

       3) 正确的使用序列化机制,没有必要序列化的成员变量需要标识为transient;

       4) 使用NIO技术。

3.6 JDBC
       1) 使用正确的JDBC驱动,尽可能地选择最新的JDBC驱动;

       最新的JDBC驱动不仅优化了性能,而且提供了更多的性能更好的接口供开发人员使用。

       2) 使用应用服务器自带的连接池,而不要使用自己的连接池或干脆不用连接池;

       3) 在使用完数据库资源后,需依次关闭ResultSet,Statement和Connection;

       4) 手动控制事务,使用connection.setAutoCommit(false)关闭自动提交,使用executeBatch()进行批量更新;

       5) 业务复杂或者大数据量操作时使用存储过程;

       6) ResultSet.next()极其消耗性能,建议使用RowSet替代ResultSet;

       7) 把所有的字符数据都保存为Unicode,Java以UniCode形式处理所有数据,数据库驱动程序不必再执行转换过程;

       8) 尽可能的优化SQL语句;

       9) 少用join,多用index;

       10) 使用EXPLAIN工具监控SQL语句的执行,以确定瓶颈所在;

11)   不要使用 SELECT * ..., 使用 SELECT Field1, Field1 ...;

12)   通过index获取字段,而不要使用名字去获取,例如resultSet.getString(1) 而不是 resultSet.getString("field1");

13)   缓存数据,避免重复查询;

14)   考虑使用内存数据库;

15)   调整fetch size进行批量查询;

16)   尽可能的使Java数据类型和数据库类型相匹配,转换数据在匹配不好的数据类型间效率太差;

17)  避免使用低效的metadata调用,尤其是getBestRowIdentifier( ), getColumns( ), getCrossReference( ), getExportedKeys( ), getImportedKeys( ), getPrimaryKeys( ), getTables( ), and getVersionColumns( );

18)   使用metadata查询减少数据库网络通信量;

19)   使用最低的事务隔离级别;

20)   使用乐观锁机制;

21)   把应用服务器和数据库分散在不同的机器中,性能可能会更好。

3.7 Servlet和JSP
       1) Session的使用;

       应用服务器保存很多会话时,容易造成内存不足,所以尽量减少Session的使用,放置到Session中的对象不应该是大对象,最好是简单的小对象,实 现串行化接口。当会话不再需要时,应当及时调用invalidate()方法清除会话。而当某个变量不需要时,及时调用 removeAttribute()方法清除变量。当session终止时需要清除不必要的资源,实现 HttpSessionBindingListener接口的valueUnbound()方法。

       2) 使用include directive,而不使用include action;

       目前在JSP页面中引入外部资源的方法主要有两种:include directive和include action。Include directive:例如<%@ include file=”copyright.html” %>,该指令在编译时引入指定的资源。在编译之前,带有include指令的页面和指定的资源被合并成一个文件。被引用的资源在编译时就确定,比运 行时才确定资源更高效。Include action:例如< jsp:include page=”copyright.jsp” />,该动作引入指定页面执行后生成的结果。由于它在运行时完成,因此对输出结果的控制更加灵活。但是,只有当引用的内容被频繁改变时,或者在对主 页面的请求没有出现之前,被引用的页面无法确定时,使用include action才合算。

       3) 对于那些无需跟踪会话状态的jsp,关闭自动创建的会话可以节省一些资源。使用如下page指令: < %@ page session=”false” %>;

       4) 尽量不要把jsp页面定义为单线程,应设置为< %@page isThreadSafe=”true” %>;

       5) 在jsp页面最好使用输出缓存功能,如:< %@page buffer=”32kb” %>;

       6) 在servlet之间跳转时,forward比sendRedirect更有效;

       7) 设置HttpServletResponse缓冲区,如:response.setBufferSize(20000);

       8) 建议在servlet里使用ServletOutputStream输出图片等对象;

9) 不要使用SingleThreadModel,使Servlet是线程安全的,但是尽可能的减少消耗在同步代码上的时间,使用足够多的servlet去响应用户的请求;

10) 尽可能的使useBean的范围在page范围内;

11)   Servlet的inti()和destroy()或jspInit()和jspDestroy()方法用于创建和删除昂贵的资源,例如缓存对象和数据库连接;

12)   避免使用反向DNS查找;

13)   预编译JSP页面;

14)   尽可能的在客户段校验数据;

15)   禁止自动装载特色防止周期性的装载servlet和jsp。

3.8 EJB
       由于EJB2.0已经很少项目在用了,EJB3.0再成熟一点,我再补充这一部分吧!



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [java 性能调优] 推荐:

Java 性能调优

- - 编程语言 - ITeye博客
1.用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用. 但如果一个对象实现了Cloneable接口,我们可以调用它的clone()方法. clone()方法不会调用任何类构造函数. 在使用设计模式(Design Pattern)的场合,如果用Factory模式创建对象,则改用clone()方法创建新的对象实例非常简单.

[原]Java性能调优

- - 傲慢的上校的专栏
写Java也有n年了,现在还是有不少的坏的代码习惯,也通过学习别人的代码学到了不少好的习惯. 留给自己做个警戒,提示以后写代码的时候注意. 在文章的后面,会提供整理的原材料下载. 1、尽量少用new生成新对象.         用new创建类的实例时,构造雨数链中所有构造函数都会被自动调用,操作速度较慢.

Java性能调优续

- - 编程语言 - ITeye博客
       下面列出一些常见的关于字符串优化的策略,简单的我就不多作解释了. 1) 使用规则表达式处理字符串匹配代替复杂的字符串查找和复制操作;. 2) 使用不拷贝字符串中字符的高效方法,例如String.subString()方法;. 3) 尽可能不要使用需要拷贝字符串中字符的低效方法,例如String.toUpperCase()和String.toLowercase();.

成为Java GC专家(5)—Java性能调优原则

- - ImportNew
这是“ 成为Java GC专家”系列的第五篇文章. 在第一篇 深入浅出Java垃圾回收机制中,我们已经学习了不同的GC算法流程、GC的工作原理、新生代(Young Generation)和老年代(Old Generation)的概念. 你应该了解了JDK7中5种GC类型以及各种类型对应用程序的影响.

Java 性能调优指南 – 高性能Java

- - 码蜂笔记
本文主要基于 Java performance tuning tips or everything you want to know about Java performance in 15 minutes的翻译. 这篇指南主要调优 java 代码而不是 JVM 设置. Java 1.7.0_06 String 内部表示的改变.

Java性能调优:利用JFR生成性能日志

- - 编程语言 - ITeye博客
Java性能调优作为大型分布式系统提供高性能服务的必修课,其重要性不言而喻. 好的分析工具能起到事半功倍的效果,利用分析利器JMC、JFR,可以实现性能问题的准确定位. 本文主要阐述如何利用JFR生成性能日志. JVM_OPT中添加:-XX:+UnlockCommercialFeatures -XX:+FlightRecorder.

Java应用性能调优之调优准备

- - 后端技术杂谈 | 飒然Hang
实际的开发工作中,有时候会遇到程序突然变得响应缓慢或者进程消失的情况. 这时候就需要对程序进行问题排查和调优,找出产生问题的根源,并进行优化. 一般来说,影响程序性能的因素主要有以下几个:. CPU、内存、硬盘等硬件配置从根本上决定了应用的性能,而对于网络应用,带宽也是影响其性能的关键因素. 本章暂且抛开这些方面不讲,主要讲述针对操作系统和应用程序的调优方法.

HBase性能调优

- - 学着站在巨人的肩膀上
我们经常看到一些文章吹嘘某产品如何如何快,如何如何强,而自己测试时却不如描述的一些数据. 其实原因可能在于你还不是真正理解其内部结构,对于其性能调优方法不够了解. 本文转自TaoBao的Ken Wu同学的博客,是目前看到比较完整的HBase调优文章. 原文链接:HBase性能调优. 因官方Book Performance Tuning部分章节没有按配置项进行索引,不能达到快速查阅的效果.

hbase性能调优

- - 数据库 - ITeye博客
   1)、hbase.regionserver.handler.count:该设置决定了处理RPC的线程数量,默认值是10,通常可以调大,比如:150,当请求内容很大(上MB,比如大的put、使用缓存的scans)的时候,如果该值设置过大则会占用过多的内存,导致频繁的GC,或者出现OutOfMemory,因此该值不是越大越好.

Hadoop性能调优

- - 开源软件 - ITeye博客
是否对任务进行profiling,调用java内置的profile功能,打出相关性能信息. 对几个map或reduce进行profiling. 非常影响速度,建议在小数据量上尝试. 1表示不reuse,-1表示无限reuse,其他数值表示每个jvm reuse次数. reuse的时候,map结束时不会释放内存.