小
小猪
Unregistered / Unconfirmed
GUEST, unregistred user!
Java虚拟机(JVM)的性能优化
??Java体系结构由四个不同却又相互关联的部分组成:语言本身、class文件格式、Java API 库和JVM。当执行一个Java程序时,源代码是用Java 语言写成,它被编译成class文件格式,运行在JVM中。同时,Java程序调用Java API 库的方法,访问系统资源。JVM 和 Java API 库形成了编译和运行环境,就叫做Java平台。JVM是基于堆栈的(stack-based),而不象汇编语言是基于寄存器的(register based)。JVM是一个动态堆栈基础上的抽象的计算机体系结构,提供了push、pop来操作数据。JVM的主要功能是装载class文件,执行字节码。java平台的执行工作量分为四个部分:
1. 字节码的执行:JVM花费大概一半的时间来解释字节码。
2. Garbage collection(垃圾回收)
3. 线程管理
4. 动态操作:类装载、绑定检查、安全检查、动态类装载、异常捕获、反射机制、本地方法的翻译。
其中,对象的垃圾回收会占用运行时间,造成程序的短暂中断。
使用HotSpot
HotSpot JVM作为java 2 SDK 的一个附加模块,使用了state-of-the-art 技术大大的提高了系统性能:
1. 适应编译:HotSpot JVM会在程序的运行过程中分析性能的瓶颈("hot spots"),然后编译这些和性能提高最紧密的部分。
2. 改善的Garbage collection
3. 线程同步优化
??HotSpot JVM使用两个机器字(two-machine-word) 作为对象的header,而不象大多数JVM使用三个机器字,这样大约可以节省10%的堆内存空间,加速了对所有对象的扫描。
HotSpot JVM 也丢弃了 handle 的概念,对象引用的实现是通过直接指针,减少了内存的使用和提高了处理速度。访问实例变量象C 语言一样的高效。
可以去http://java.sun.com/products/hotspot/2.0/download.html 下载Java HotSpotTM Server VM 2.0,执行安装即可。如果需要可以针对 jdk 和 jre分别进行安装。
HotSpot JVM 分为 client 和 server 版本,分别针对典型的客户端应用程序和服务器端应用进行了优化。Jdk1.3安装后就包含了 Java HotSpot Client VM,上面安装的是Java HotSpot Server VM。
可以通过命令行参数选择要使用的JVM:
· java -server :Java HotSpot Server VM
· java -hotspot : Java HotSpot Client VM
· java -classic : Java 2 Classic VM
缺省情况是使用 HotSpot Client VM。可以用 java -server -version 来查看版本信息,确定是否以正确安装。
只要针对不同的应用,选择Client 或Server HotSpot VM。对于Server-side应用,有时性能会提高20%,只要简单的在命令行启动Server 时加上 -server 。
Garbage Collection
HotSpot JVM 提供了三种类型的垃圾回收算法,分别是:
1. Copy/scavenge collection
2. Mark-compact collection
3. Incremental (train) collection
具体的含义我不解释了,有兴趣可以查看相关的文档。
一个 JVM 的吞吐量是指除去 GC 消耗的时间占总执行时间的百分比。因此,80%的吞度量就是说 GC 消耗了20%的 JVM 处理时间。当你的应用程序运行时,JVM 的 GC 会造成程序的暂停。
堆内存被分成了 new 和 old 两部分,如下图:
|Perm| old |ss#1|ss#2| new |
|64MB|<-----------old------------>|<------new-------->|
|JVM |<---------------------程序使用------------------>|
|<-------------------------堆内存空间----------------->|
new 部分包括新创建对象区和两个 survivor 区(SS#1和SS#2),新创建的对象分配内存在 new 中,长时间存活的对象被移动到了 old 部分。Perm 是一个永久区域,分配给JVM本省,可以通过 命令行参数 -XX:MaxPermSize=64m 来设置。
当 new 被填满后,会触发"辅助" GC,把存在足够长时间的对象移动到 old 中。当 old 中也被填满了,会触发"主" GC ,将遍历堆内存中的所有对象。可以看出,"主" GC 会消耗更多的时间。足够大的 new 会适合需要大量创建存在时间很短的对象,而 old 如果不够大会频繁的触发"主" GC ,大大降低了性能。所以,我们的任务就是如何设置堆内存的大小以及如何规划 new 和 old 区域的比例来适合我们应用。
"辅助" GC 使用Copy/scavenge collection 算法,"主"GC 使用 Mark-compact collection。
Heap分配策略
通过命令行参数,我们可以设置堆的大小和分配"new"、"old"的比例。一些常用参数如下:
-Xms<size> 设置java堆内存的初始大小
-Xmx<size> 设置java堆内存的最大值
-XX:NewSize=<size> 设置"new"的初始大小
-XX:MaxNewSize=<size> 设置"new"的最大值
-XX:NewRatio=2 设置"old"和"new"的比率
-XX:SurvivorRation=64 设置"ss#1"和"new"的比率
-XX:MaxPermSize=64M 设置不可变区域
详细的参数设置请参看相关的文档。
如何来规划我们的堆内存分配策略呢?没有一个明确详细的规定,只能根据我们具体的应用进行调节,使性能达到最优化。这种优化方法不需要程序员改变代码,但有时效果会很明显。下面总结了一些操作建议:
· 如果GC成为了瓶颈,请定制你的堆内存分配
· 分配尽可能多的内存给JVM。但如果过多,会引起内存和硬盘之间的交换,反而降低的性能。你可以分配80%的可用RAM 给JVM。
· 如果是Server-Side应用,请加 -server参数。这样,缺省的NewRatio 是2,SurvivorRatio 是 25 ,适合大部分应用。也可以用NewSize、MaxNewSize来设置。
· 设置- Xms 和 -Xmx 的大小相等,可以避免在每次 GC 后调整堆内存的大小。
· 同样道理设置NewSize、MaxNewSize相等。
· "new"的大小最好不要大于"old"的一半。
??Java体系结构由四个不同却又相互关联的部分组成:语言本身、class文件格式、Java API 库和JVM。当执行一个Java程序时,源代码是用Java 语言写成,它被编译成class文件格式,运行在JVM中。同时,Java程序调用Java API 库的方法,访问系统资源。JVM 和 Java API 库形成了编译和运行环境,就叫做Java平台。JVM是基于堆栈的(stack-based),而不象汇编语言是基于寄存器的(register based)。JVM是一个动态堆栈基础上的抽象的计算机体系结构,提供了push、pop来操作数据。JVM的主要功能是装载class文件,执行字节码。java平台的执行工作量分为四个部分:
1. 字节码的执行:JVM花费大概一半的时间来解释字节码。
2. Garbage collection(垃圾回收)
3. 线程管理
4. 动态操作:类装载、绑定检查、安全检查、动态类装载、异常捕获、反射机制、本地方法的翻译。
其中,对象的垃圾回收会占用运行时间,造成程序的短暂中断。
使用HotSpot
HotSpot JVM作为java 2 SDK 的一个附加模块,使用了state-of-the-art 技术大大的提高了系统性能:
1. 适应编译:HotSpot JVM会在程序的运行过程中分析性能的瓶颈("hot spots"),然后编译这些和性能提高最紧密的部分。
2. 改善的Garbage collection
3. 线程同步优化
??HotSpot JVM使用两个机器字(two-machine-word) 作为对象的header,而不象大多数JVM使用三个机器字,这样大约可以节省10%的堆内存空间,加速了对所有对象的扫描。
HotSpot JVM 也丢弃了 handle 的概念,对象引用的实现是通过直接指针,减少了内存的使用和提高了处理速度。访问实例变量象C 语言一样的高效。
可以去http://java.sun.com/products/hotspot/2.0/download.html 下载Java HotSpotTM Server VM 2.0,执行安装即可。如果需要可以针对 jdk 和 jre分别进行安装。
HotSpot JVM 分为 client 和 server 版本,分别针对典型的客户端应用程序和服务器端应用进行了优化。Jdk1.3安装后就包含了 Java HotSpot Client VM,上面安装的是Java HotSpot Server VM。
可以通过命令行参数选择要使用的JVM:
· java -server :Java HotSpot Server VM
· java -hotspot : Java HotSpot Client VM
· java -classic : Java 2 Classic VM
缺省情况是使用 HotSpot Client VM。可以用 java -server -version 来查看版本信息,确定是否以正确安装。
只要针对不同的应用,选择Client 或Server HotSpot VM。对于Server-side应用,有时性能会提高20%,只要简单的在命令行启动Server 时加上 -server 。
Garbage Collection
HotSpot JVM 提供了三种类型的垃圾回收算法,分别是:
1. Copy/scavenge collection
2. Mark-compact collection
3. Incremental (train) collection
具体的含义我不解释了,有兴趣可以查看相关的文档。
一个 JVM 的吞吐量是指除去 GC 消耗的时间占总执行时间的百分比。因此,80%的吞度量就是说 GC 消耗了20%的 JVM 处理时间。当你的应用程序运行时,JVM 的 GC 会造成程序的暂停。
堆内存被分成了 new 和 old 两部分,如下图:
|Perm| old |ss#1|ss#2| new |
|64MB|<-----------old------------>|<------new-------->|
|JVM |<---------------------程序使用------------------>|
|<-------------------------堆内存空间----------------->|
new 部分包括新创建对象区和两个 survivor 区(SS#1和SS#2),新创建的对象分配内存在 new 中,长时间存活的对象被移动到了 old 部分。Perm 是一个永久区域,分配给JVM本省,可以通过 命令行参数 -XX:MaxPermSize=64m 来设置。
当 new 被填满后,会触发"辅助" GC,把存在足够长时间的对象移动到 old 中。当 old 中也被填满了,会触发"主" GC ,将遍历堆内存中的所有对象。可以看出,"主" GC 会消耗更多的时间。足够大的 new 会适合需要大量创建存在时间很短的对象,而 old 如果不够大会频繁的触发"主" GC ,大大降低了性能。所以,我们的任务就是如何设置堆内存的大小以及如何规划 new 和 old 区域的比例来适合我们应用。
"辅助" GC 使用Copy/scavenge collection 算法,"主"GC 使用 Mark-compact collection。
Heap分配策略
通过命令行参数,我们可以设置堆的大小和分配"new"、"old"的比例。一些常用参数如下:
-Xms<size> 设置java堆内存的初始大小
-Xmx<size> 设置java堆内存的最大值
-XX:NewSize=<size> 设置"new"的初始大小
-XX:MaxNewSize=<size> 设置"new"的最大值
-XX:NewRatio=2 设置"old"和"new"的比率
-XX:SurvivorRation=64 设置"ss#1"和"new"的比率
-XX:MaxPermSize=64M 设置不可变区域
详细的参数设置请参看相关的文档。
如何来规划我们的堆内存分配策略呢?没有一个明确详细的规定,只能根据我们具体的应用进行调节,使性能达到最优化。这种优化方法不需要程序员改变代码,但有时效果会很明显。下面总结了一些操作建议:
· 如果GC成为了瓶颈,请定制你的堆内存分配
· 分配尽可能多的内存给JVM。但如果过多,会引起内存和硬盘之间的交换,反而降低的性能。你可以分配80%的可用RAM 给JVM。
· 如果是Server-Side应用,请加 -server参数。这样,缺省的NewRatio 是2,SurvivorRatio 是 25 ,适合大部分应用。也可以用NewSize、MaxNewSize来设置。
· 设置- Xms 和 -Xmx 的大小相等,可以避免在每次 GC 后调整堆内存的大小。
· 同样道理设置NewSize、MaxNewSize相等。
· "new"的大小最好不要大于"old"的一半。