`
maosheng
  • 浏览: 550283 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java 高性能编程注意事项

    博客分类:
  • Java
阅读更多
1. 尽量在合适的场合使用单例

使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:

第一,控制资源的使用,通过线程同步来控制资源的并发访问;
第二,控制实例的产生,以达到节约资源的目的;
第三,控制数据共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信。

2. 尽量避免随意使用静态变量

要知道,当某个对象被定义为stataic变量所引用,那么gc通常是不会回收这个对象所占有的内存,如

Java代码
public class A{ 
static B b = new B(); 


此时静态变量b的生命周期与A类同步,如果A类不会卸载,那么b对象会常驻内存,直到程序终止。

3. 尽量避免过多过常的创建Java对象

尽量避免在经常调用的方法,循环中new对象,由于系统不仅要花费时间来创建对象,而且还要花时间对这些对象进行垃圾回收和处理,在我们可以控制的范围内,最大限度的重用对象,最好能用基本的数据类型或数组来替代对象。

4. 尽量使用final修饰符

带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。为String类指定final防止了使用者覆盖length()方法。另外,如果一个类是final的,则该类所有方法都是final的。Java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50%。

5. 尽量使用局部变量

调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。

6. 尽量处理好包装类型和基本类型两者的使用场所

虽然包装类型和基本类型在使用过程中是可以相互转换,但它们两者所产生的内存区域是完全不同的,基本类型数据产生和处理都在栈中处理,包装类型是对象,是在堆中产生实例。在集合类对象,有对象方面需要的处理适用包装类型,其他的处理提倡使用基本类型。

7. 慎用synchronized,尽量减小synchronize的方法

都知道,实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

8. 尽量使用StringBuilder和StringBuffer进行字符串连接

这个就不多讲了。

9. 尽量使用基本数据类型代替对象

String str = "hello";
上面这种方式会创建一个“hello”字符串,而且JVM的字符缓存池还会缓存这个字符串;
String str = new String("hello");
此时程序除创建字符串外,str所引用的String对象底层还包含一个char[]数组,这个char[]数组依次存放了h,e,l,l,o

10. 单线程应尽量使用HashMap、ArrayList

HashTable、Vector等使用了同步机制,降低了性能。

11. 尽量合理的创建HashMap

当你要创建一个比较大的hashMap时,充分利用另一个构造函数
public HashMap(int initialCapacity, float loadFactor)
避免HashMap多次进行了hash重构,扩容是一件很耗费性能的事,在默认中initialCapacity只有16,而loadFactor是 0.75,需要多大的容量,你最好能准确的估计你所需要的最佳大小,同样的Hashtable,Vectors也是一样的道理。

12. 尽量减少对变量的重复计算


for(int i=0;i<list.size();i++)
应该改为
for(int i=0,len=list.size();i<len;i++)
并且在循环中应该避免使用复杂的表达式,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。

13. 尽量避免不必要的创建


A a = new A();
if(i==1){list.add(a);}
应该改为
if(i==1){
A a = new A();
list.add(a);}

14. 尽量在finally块中释放资源

程序中使用到的资源应当被释放,以避免资源泄漏。这最好在finally块中去做。不管程序执行的结果如何,finally块总是会执行的,以确保资源的正确关闭。

15. 尽量使用移位来代替'a/b'的操作

"/"是一个代价很高的操作,使用移位的操作将会更快和更有效

int num = a / 4;
int num = a / 8;
应该改为
int num = a >> 2;
int num = a >> 3;
但注意的是使用移位应添加注释,因为移位操作不直观,比较难理解

16.尽量使用移位来代替'a*b'的操作

同样的,对于'*'操作,使用移位的操作将会更快和更有效

int num = a * 4;
int num = a * 8;
应该改为
int num = a << 2;
int num = a << 3;

17. 尽量确定StringBuffer的容量

StringBuffer 的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再 丢弃旧的数组。在大多数情况下,你可以在创建 StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。
如:StringBuffer buffer = new StringBuffer(1000); 

18. 尽量早释放无用对象的引用

大部分时,方法局部引用变量所引用的对象 会随着方法结束而变成垃圾,因此,大部分时候程序无需将局部,引用变量显式设为null。
例如:

Java代码
Public void test(){ 
Object obj = new Object(); 
…… 
Obj=null; 


上面这个就没必要了,随着方法test()的执行完成,程序中obj引用变量的作用域就结束了。但是如果是改成下面:

Java代码
Public void test(){ 
Object obj = new Object(); 
…… 
Obj=null; 
//执行耗时,耗内存操作;或调用耗时,耗内存的方法 
…… 


这时候就有必要将obj赋值为null,可以尽早的释放对Object对象的引用。

19. 尽量避免使用二维数组

二维数据占用的内存空间比一维数组多得多,大概10倍以上。

20. 尽量避免使用split

除非是必须的,否则应该避免使用split,split由于支持正则表达式,所以效率比较低,如果是频繁的几十,几百万的调用将会耗费大量资源,如果确实需 要频繁的调用split,可以考虑使用apache的StringUtils.split(string,char),频繁split的可以缓存结果。

21. ArrayList & LinkedList

一 个是线性表,一个是链表,一句话,随机查询尽量使用ArrayList,ArrayList优于LinkedList,LinkedList还要移动指 针,添加删除的操作LinkedList优于ArrayList,ArrayList还要移动数据,不过这是理论性分析,事实未必如此,重要的是理解好2 者得数据结构,对症下药。

22. 尽量使用System.arraycopy ()代替通过来循环复制数组

System.arraycopy() 要比通过循环来复制数组快的多

23. 尽量缓存经常使用的对象

尽可能将经常使用的对象进行缓存,可以使用数组,或HashMap的容器来进行缓存,但这种方式可能导致系统占用过多的缓存,性能下降,推荐可以使用一些第三方的开源工具,如EhCache,Oscache进行缓存,他们基本都实现了FIFO/FLU等缓存算法。

24. 尽量避免非常大的内存分配

有时候问题不是由当时的堆状态造成的,而是因为分配失败造成的。分配的内存块都必须是连续的,而随着堆越来越满,找到较大的连续块越来越困难。

25. 慎用异常

当创建一个异常时,需要收集一个栈跟踪(stack track),这个栈跟踪用于描述异常是在何处创建的。构建这些栈跟踪时需要为运行时栈做一份快照,正是这一部分开销很大。当需要创建一个 Exception 时,JVM 不得不说:先别动,我想就您现在的样子存一份快照,所以暂时停止入栈和出栈操作。栈跟踪不只包含运行时栈中的一两个元素,而是包含这个栈中的每一个元素。

如 果您创建一个 Exception ,就得付出代价。好在捕获异常开销不大,因此可以使用 try-catch 将核心内容包起来。从技术上讲,您甚至可以随意地抛出异常,而不用花费很大的代价。招致性能损失的并不是 throw 操作——尽管在没有预先创建异常的情况下就抛出异常是有点不寻常。真正要花代价的是创建异常。幸运的是,好的编程习惯已教会我们,不应该不管三七二十一就 抛出异常。异常是为异常的情况而设计的,使用时也应该牢记这一原则。


26. 尽量减少对变量的重复计算

对方法的调用,即使方法中只有一句语句,也是有消耗的,包括创建栈帧、调用方法时保护现场、调用方法完毕时恢复现场等。所以例如下面的操作:

for (int i = 0; i < list.size(); i++)
{...}

建议替换为:

for (int i = 0, int length = list.size(); i < length; i++)
{...}

这样,在list.size()很大的时候,就减少了很多的消耗


27. 尽量采用懒加载的策略,即在需要的时候才创建

String str = "aaa";

if (i == 1)
{

list.add(str);

}
建议替换为:

if (i == 1)
{

String str = "aaa";

list.add(str);

}


28. 尽量使用HashMap、ArrayList、StringBuilder,除非线程安全需要,否则不推荐使用Hashtable、Vector、StringBuffer,后三者由于使用同步机制而导致了性能开销















分享到:
评论

相关推荐

    Java编程中为了性能需做的26件事 (编程必看)

    Java编程中为了性能需做的26件事 (编程必看) 对于一个有2年以上工作经验的程序员,也未必能搞清楚java编程时性能的注意事项;所以建议新手老手必看;

    java并发编程从入门到精通

    《Java并发编程从入门到精通》作者结合自己10多年Java并发编程经验,详细介绍了Java并发编程的基础概念、工作原理、编程技巧和注意事项,对Java高性能高并发编程有极大的参考价值。 《Java并发编程从入门到精通》...

    [17个软件测试文档]-17性能测试计划注意事项

    [17个软件测试文档] 17性能测试计划注意事项 已全部上传 [17个软件测试文档] 16软件性能测试从这里开始V1[1] 0 0 0 http: download csdn net detail cleopard 8344281 [17个软件测试文档] 15压力测试和服务器稳定...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    │ Java面试题84:项目流程和业务注意事项.mp4 │ 面试必问-Mysql索引背后的故事 │ ├─java面试专属 │ ├─1.面试必考之HashMap源码分析与实现 │ │ 1.面试必考之HashMap源码分析与实现.mp4 │ │ │ ├─2....

    实战Java高并发程序设计(第2版)PPT模板.pptx

    4锁的优化及注意事项 04 实战Java高并发程序设计(第2版)PPT模板全文共25页,当前为第9页。 4锁的优化及注意事项 4.1有助于提高锁性能的几点建议 4.2java虚拟机对锁优化所做的努力 4.3人手一支笔:threadlocal 4.4...

    秦小波-编写高质量代码:改善Java程序的151个建议(带索引书签目录高清扫描版).pdf

    第4~9章重点针对jdk api的使用提出了80条建议,例如字符串的拼接方法该如何选择、枚举使用时有哪些注意事项、出现nullpointerexception该如何处理、泛型的多重界限该如何使用、多线程编程如何预防死锁,等等;...

    个人金融管理应用案例Java代码、建议及注意项.docx

    Java作为一种静态类型、多范式...精通Java编程需要持续的实践和学习,但它为开发者提供了一个强大而灵活的平台,用以构建复杂且高性能的应用程序。遵循上面提到的建议和注意事项,可以系统地学习Java并成功地实施项目。

    编写高质量代码之Java_nodrm.azw3

    第4~9章重点针对jdk api的使用提出了80条建议,例如字符串的拼接方法该如何选择、枚举使用时有哪些注意事项、出现nullpointerexception该如何处理、泛型的多重界限该如何使用、多线程编程如何预防死锁,等等;...

    java多线程tcpsocketserver源码-Java-Book:Java学习资料整理

    java多线程tcp socket server源码 ...--(编写代码过程中的一些最佳实践,注意事项。现在已经出第二版了,增加了lambada的内容) JAVA网络编程 第4版 --(BIO socket编程,现在基本不用了) 性能优化 Java性

    Java-Concurrency-Progamming-Tutorial:BAT华为大厂一线工程师四年磨一剑精心编排 Java 高并发编程案例代码 & 教程 & 面试题集锦。详细文档讲解请阅读本人的知识库仓:https

    1 目标 致力于建立全球最完善的 Java 高并发理论体系。...原子性部分, atomic包下相关类、CAS原理、Unsafe类、synchronized关键字等的使用及注意事项 可见性部分,主要介绍的是volatile关键字的规则和使用,及syn

    Tcl_TK编程权威指南pdf

    注意事项 第15章 国际化(internationalization) 字符集与编码 消息目录 第16章 事件驱动的编程 tcl事件循环 after命令 fileevent命令 vwait命令 fconfigure命令 第17章 套接字编程 客户端套接字 ...

    精通并发与 netty 视频教程(2018)视频教程

    Netty引用计数的实现机制与自旋锁的使用技巧 82_Netty引用计数原子更新揭秘与AtomicIntegerFieldUpdater深度剖析 83_AtomicIntegerFieldUpdater实例演练与volatile关键字分析 84_Netty引用计数注意事项与内存泄露...

    springmybatis

    性能也比hibernate好。而且也比较轻量级,因为当时在项目中,没来的及做很很多笔记。后来项目结束了,我也没写总结文档。已经过去好久了。但最近突然又对这个ORM 工具感兴趣。因为接下来自己的项目中很有可能采用这...

    《算法》中文版,Robert Sedgewick,塞奇威克

    1.4.7 注意事项 1.4.8 处理对于输入的依赖 1.4.9 内存 1.4.10 展望 1.5 案例研究:union-find算法 1.5.1 动态连通性 1.5.2 实现 1.5.3 展望 第2章 排序 2.1 初级排序算法 2.1.1 游戏规则 2.1.2 选择排序...

    二十三种设计模式【PDF版】

    提供 Java运行性能,降低小而大量重复的类的开销. C. 行为模式 设计模式之 Command(命令) 什么是将行为封装,Command 是最好的说明. 设计模式之 Observer(观察者) 介绍如何使用 Java API 提供的现成 Observer ...

    《Android应用开发揭秘》源码

     14.3.2 游戏引擎设计注意事项  14.4 游戏引擎实现  14.4.1 Activity类实现  14.4.2 流程控制和线程  14.4.3 游戏对象与对象管理  14.4.4 图形引擎  14.4.5 物理引擎  14.4.6 事件模块  14.4.7 工具模块  ...

    Android应用开发揭秘

    14.3.2 游戏引擎设计注意事项 14.4 游戏引擎实现 14.4.1 Activity类实现 14.4.2 流程控制和线程 14.4.3 游戏对象与对象管理 14.4.4 图形引擎 14.4.5 物理引擎 14.4.6 事件模块 14.4.7 工具模块 14.4.8 脚本引擎、...

    《Android应用开发揭秘》附带光盘代码.

     14.3.2 游戏引擎设计注意事项  14.4 游戏引擎实现  14.4.1 Activity类实现  14.4.2 流程控制和线程  14.4.3 游戏对象与对象管理  14.4.4 图形引擎  14.4.5 物理引擎  14.4.6 事件模块  14.4.7 工具模块  ...

    算法,4th,塞奇威克 (Robert Sedgewick)韦恩 (Kevin Wayne), 谢路云 译.azw3

    1.4.7 注意事项 1.4.8 处理对于输入的依赖 1.4.9 内存 1.4.10 展望 1.5 案例研究:union—find算法 1.5.1 动态连通性 1.5.2 实现 1.5.3 展望 第2章 排序 2.1 初级排序算法 2.1.1 游戏规则 2.1.2 选择排序...

Global site tag (gtag.js) - Google Analytics