很多懂java或者参加过java培训的同学都知道,Java的一些性能是可以优化的,本文呢综合了各种Java性能优化的研究成果,涵盖从JDK到Java集合使用、场景用例到和工具。希望对同学们有帮助.
1.如果在静态构造器中有繁重的计算,也就是耗费CPU的逻辑代码,请检查其运行时间是否过度?如果是,将这些逻辑迁移到另外一个单独的帮助类中。StaticconstructorcodeisnotJIT-optimizedinalotofcases
2.在进行byte[]作为String的构造参数时,需要将byte数组的一部分做个复制拷贝,否则,构造器会为整个原始缓冲做一个临时拷贝;试图避免不必要的内存分配,因为在内存使用超过1G+以上时会影响程序的性能,Inefficientbyte[]toStringconstructor
3.变量对于大多数程序是非常有用的,因为它们缩短了代码,但是当变量的所有成员已经确认是不变的常量,那么使用预编译的数组替代。Javavarargsperformanceissues:
4.尽可能使用StringBuilder替代StringBuffer。PrimitivetypestoStringconversionandStringconcatenation
5.使用闪存SSD替代传统的硬盘HDD,这样你可以将你的应用程序从I/O-bound转变到CPU-bound,这对于设计到read/write流操作特别有用;现代操作系统都是在后台写数据,不会堵塞你的应用,你的写操作只有在操作系统写入磁盘的速度慢于你的应用产生数据的速度时,才会堵塞你的写操作请求:I/Oboundalgorithms:SSDvsHDD
6.如果你的内存中有字符串或带有String字段的对象的大量集合,在某些情况下,字少10%场景,这些字符串实际上可能会转换为基本类型的值,你可以使用Object字段替代你的String字段,使用其提供的pack/unpack方法在字符串和对象之间来回转换,这样节省内存。如果你不将字符串转换为基本类型,可以考虑将字符串转为UTF-8的byte[],可以随时将byte[]转回原始字符串。Stringpackingpart2:convertingStringstoanyotherobjects
7.如果有大量重复的字符串,使用String.intern()减少内存损耗,提高性能:ReducingmemoryusagewithString.intern()、String.interninJava6,7and8-part3、String.interninJava6,7and8-multithreadedaccess
8.尝试使用Googleprotobuf或类似编码技术编码你整数数据,特别是这些数据值很小的情况下,这样你会得到数据量大幅度减小后导致的低CPU损耗,能够帮助你提高每个时间单元中存储或读取更多消息数量。
9.如果使用arraylist/set/map时,其key或值是基本类型,那么使用Trove的maps/sets替代JDKmaps/sets,可以节省大量内存。Trovelibrary:usingprimitivecollectionsforperformance
10.当你的应用堆heap大小超过32G时,JVM会切换到64位的对象引用,意味着你的应用已经结束了占用更少Heap空间的阶段。GoingoverXmx32Gheapboundarymeansyouwillhavelessmemoryavailable
11.如果你使用内部类,缺省使用静态的内部类;如果你使用一堆小的集合Collection,那么试试使用java.util.Collections.empty*/singleton*方法实现小集合的内存高效率存储;使用BitSet替代boolean的arrays/lists或一系列integer整数类型,bitset是内存和CPU缓存都很友好。AfewmorememorysavingtechniquesinJava
12.不要在多线程中共享一个java.util.Random实例,将其包装在ThreadLocal中,Java7中使用java.util.concurrent.ThreadLocalRandom替代java.util.Random。
13.如果你希望有快速的Base64编码器,使用Java8的java.util.Base64
14.不要使用exception,每个exception启动需要1毫秒:CreatinganexceptioninJavaisveryslow
15.如果你使用:
if(!set.contains(key))
{
set.add(key);
//someextracodehere
}
直接使用add更快:
if(set.add(key)){
//sameextracodecouldbeaddedhere
}
同样,contains+remove可以被remove直接替代。
16.如果要使用压缩,考虑使用LZ4。Performanceofvariousgeneralcompressionalgorithms-someofthemareunbelievablyfast!
17.使用ByteBuffer替代ByteArrayOutputStream。java.io.ByteArrayOutputStream
18.如果你希望计算几天这样的短天数,那么基于int/long进行手工实现会更快些。JSR310-Java8Date/Timelibraryperformance(aswellasJodaTime2.3andj.u.Calendar)
19.使用Matcher和Pattern替代String.matches,split,replaceAll,replaceFirst等方法。Regexp-relatedmethodsofString
20.如果你希望有一个快速的LinkedList代码实现,考虑下面规则:
使用ArrayDeque实现基于队列queue-based的算法
使用LinkedList的ListIterator
避免使用任何LinkedList方法接受或返回集合中元素的索引。
再次检查是否有理由使用LinkedList
21.如果使用ArrayList,考虑下面规则:
将元素追加到集合尾部。
也从尾部移除元素
避免contains,indexOf和remove(Object)方法
避免更多的removeAll和retainAll方法
使用subList(int,int).clear()来清除集合中的一部分。
22.Java8中使用G1垃圾回收机制时,使用减少字符串重复配置:-XX:+UseG1GC-XX:+UseStringDeduplication。
在不久的将来,多智时代一定会彻底走入我们的生活,有兴趣入行未来前沿产业的朋友,可以收藏 多智时代 ,及时获取人工智能、大数据、云计算和物联网的前沿资讯和基础知识,让我们一起携手,引领人工智能的未来!