java性能优化

来源:互联网 发布:java简单游戏编程 编辑:程序博客网 时间:2024/06/14 20:40

    在java性能优化方面主要考虑两个主要的方面:一个是应用程序的构造方面是不是最优化,一个是在不改变代码的情况下对部署平台和环境上下功夫,包括对JVM的微调。下面就从代码编写和JVM两个方面进行描述:

一、    减少创建对象和GC,主要有下面几点需要注意:

1)         如有可能尽量使用基本变量,而不是使用封装对象,比如:Integer

2)         缓存那些濒繁使用的对象,而不是一遍又一遍重复创建相同的对象。

3)         使用StringBuffer创建和处理需要濒繁变动的字符串,而不是使用String,因为String需要创建其它对象来进行处理当前对象,但最终还是要被GC所处理。

4)         避免过度地进行java控制台的写操作,这样可以减少字符串处理,文本格式化以及输出所带来的成本。

5)         尽量使用数据库连接池,这样可以重复使用连接而不是重复创建和关闭连接。

6)         尽量使用线程池,这样可以避免不停地创建和删除线程对象,特别是在大量使用线程的时候。

7)         避免在代码中调用GC,因为GC一旦调用,除自身的线程外,其它线程将处于挂起状态。如果非要调取则要在非紧急状态或空闲状态。

8)         避免在循环内创建对象。

9)         尽早释放无用对象的引用 ,引用对象在结束活动域后可以赋值为null,特别是一些复杂的对象,比如树图数组队列,这些对象引用关系相对复杂,GC的清除效率较低,一般在它们作用域结束后,赋值null可以提高GC的清除效率。

10)    如果经常使用图片,可以使用soft引用类型(soft reference),它可以所图片放在内存中,可以避免Out of Memory.

11)    注意一些全局变量和一些静态变量,这些变量往往引起悬挂对象(dangling reference)。造成内存浪费。

二、    同步

为了减少JVM和操作系统之间的争用,应减少对同步方法的使用,更应该避免在循环中调用同步方法。

三、    数据结构

使用更有效的数据结构,避免使用更复杂的 数据结构,比如能使用数组就不要使用向量。

四、    尽可能的使用堆栈变量

局部变量存放在一个局部变量表中,静态变量或实例变量的存取的代价更高,要使用更高效的操作码来进行存取,他们存放在常数存储池中,常数存储池存放实例的类型字段方法的符号引用,静态变量和实例变量在第一次从常数存储池中访问被访问时,JVM会他们的字节码转换成更高效的操作码。尽管这样优化,还是堆栈的效率更高。考虑到这些,应尽量使用堆栈变量而不是静态或实例变量,如果非要使用这些,则可以将静态或实例变量放在局部堆栈变量中,比如在循环中存取静态或实例变量,则可以临时把它们 放在局部堆栈变量中。这样效率会更高些。

五、    避免非常大的内在分配

分本的内存块必须都是连续的,随着堆越堆越满,找一个连续的内存块越来越难,JVM的碎片整理会中断应用较长的时间。

六、    异常的开销很大

之所以这么说是因为创建一个异常要收集一个栈跟踪,栈跟踪是描述一个异常中何处建的,而构建一个栈跟踪需要运行时栈做一个快照,正是这一部分的开销很大。

七、    finalize函数

finalize函数可以用户来调用,由于没有自动实现链式调用,必须手动实现在释放资源的时候最后要写个super.finalize();以便在释放自己之后再向上释放父类资源。Finalize会降低GC的性能,释放的时间也是不确定的,释放的资源也是不确定的。一般用在一些I/0操作,数据为连接这些不易控件但很 重要的资源,但这些资源程序员应该通过程序本身来管理,以     finalize为辅的双保险方。

八、    JNI:java native interface

JNI是java平台的一部分,用于和其它语言进行交互比如C,C++。JNI提供了java平台与操作系统其它函数交互的接口,也可用于java调用其它语言所实现的功能比如汇编,C,C++等。

JVM和本机代码交互的速度非常慢,太多的JNI调用会降低性能,只要有可能就要将本机操作集合在一起,以减少JNI的调用。使用JNI代码本地处理异常,会导致性能下降,应该使用ExceptionCheck()函数,因为与ExceptionOccurred()相比它带来的开销会少一些。后者需创建一个将引用的对象,以及本地对象。

原创粉丝点击