现在处理器可以用一条指令来处理一个数组中的多条记录,例如可以同时向一个 byte
数组中读或者写 store
记录。所以要尽量使用 System.arraycopy ()这样的批量接口,
而不是自己操作数组。
JVM 优化
启用大内存页
现 在 一 个 操 作 系 统 默 认 页 是 4K
。 如 果 你 的 heap 是 4GB, 就意 味着 要执 行
1024*1024
次分配操作。所以最好能把页调大。这个配额设计操作系统,单改 Jvm 是不
行的。Linux 上的配置有点复杂,不详述。
在 Java1.6
中 UseLargePages 是默认开启的,LasrgePageSzieInBytes 被设置
成了 4M。笔者看到一些情况下配置成了 128MB,在官方的性能测试中更是配置到
256MB。
启用压缩指针
Java 的 64 的性能比 32 慢,原因是因为其指针由 32 位扩展到 64 位,虽然寻址空
间从 4GB
扩大到 256 TB,但导致性能的下降,并占用了更多的内存。所以对指针进行
压缩。压缩后的指针最多支持 32GB 内存,并且可以获得 32
位 JVM 的性能。
在
JDK6 update 23 默 认 开 启 了 , 之 前 的 版 本 可 以 使 用 -XX:
+UseCompressedOops 来启动配置。
性能可以看这个评测,性能的提升是很可观。
启用 NUMA
numa
是一个 CPU 的特性。SMP 架构下,CPU 的核是对称,但是他们共享一条系
统总线。所以 CPU
多了,总线就会成为瓶颈。在 NUMA
架构下,若干 CPU 组成一个组,
组之间有点对点的通讯,相互独立。启动它可以提高性能。
NUMA 需要硬件,操作系统,JVM 同时启用,才能启用。Linux
可以用 numactl 来
配置 numa,JVM 通过-XX:+UseNUMA 来启用。
激进优化特性
在 Java1.6 中,激进优化(AggressiveOpts)是默认开启的。激进优化是一般有一些
下一个版本才会发布的优化选项。但是有可能造成不稳定。前段时间以讹传讹的 JDK7 的
Bug,就是开启这个选项后测到的。
逃逸分析
让一个对象在一个方法内创建后,如果他传递出去,就可以称为方法逃逸 ;如果传递
到别的线程,成为线程逃逸。如果能知道一个对象没有逃逸,就可以把它分配在栈而不是
堆上,节约 GC 的时间。同时可以将这个对象拆散,直接使用其成员变量,有利于利用高
速缓存。如果一个对象没有线程逃逸,就可以取消其中一切同步操作,很大的提高性能。
但是逃逸分析是很有难度的,因为花了 cpu 去对一个对象去分析,要是他不逃逸,
就无法优化,之前的分析血本无归。所以不能使用复杂的算法,同时现在的 JVM 也没有
实现栈上分配。所以开启之后,性能也可能下降。
可以使用-XX:+DoEscapeAnalysis 来开启逃逸分析。
高吞吐量 GC 配置
对于高吞吐量,在年轻态可以使用 Parallel Scavenge,
年老态可以使用 Parallel
Old 垃圾收集器。