`
阅读更多
引言
有JAVA开发经验的朋友们一定碰到过下面的这种情况,那就是自己所开发的应用运行了一段时间后其性能或 者响应速度会有明显的降低.这是由多方面的原因造成的即有程序本身的优化问题,也有运行环境问题.此运行环境即包括硬件环境也包括软件环境.大多数人第一 个能想到的解决方法是提升硬件的配置而忽略了程序本身的运行环境JVM也提供了比较多的调优选项.本文将重点描述利用JVM的一些选项对GC进行调优.

约定:
1.读者应具备一定JAVA的知识.

2.本文中的JVM选项均以SUN公司发布的HotSpot JVM 5为准(不过大多数的选项在JVM1.3,JVM1.4中也是可用的).

3.以JAVA_HOME下demo/jfc/SwingSet2/SwingSet2.jar为例进行说明.

4.阅读本文需要一些关于GC的知识,可以到附录A中了解这些知识。

关键字:
JVM(java虚拟机),调优,GC(垃圾回收)

JVM GC调优
为了能够将JVM GC的调优能够使用在具体的实践当中,下面将利用若干个例子来说明GC的调优.
例1:Heap size 设置
JVM 堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。
当在JAVA_HOME下demo/jfc/SwingSet2/目录下执行下面的命令。
java -jar -Xmn4m -Xms16m -Xmx16m SwingSet2.jar
系统输出为:
Exception in thread "Image Fetcher 0" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Image Fetcher 3" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Image Fetcher 1" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Image Fetcher 2" java.lang.OutOfMemoryError: Java heap space
除了这些异常信息外,还会发现程序的响应速度变慢了。这说明Heap size 设置偏小,GC占用了更多的时间,而应用分配到的执行时间较少。
提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
将上面的命令换成以下命令执行则应用能够正常使用,且未抛出任何异常。
java -jar -Xmn4m -Xms16m -Xmx32m SwingSet2.jar
提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。

例2:Young Generation(-Xmn)的设置
在本例中看一下Young Generation的设置不同将有什么现象发生。
假设将Young generation 的大小设置为4M ,即执行java -jar -verbose:gc -Xmn4m -Xms32m -Xmx32m -XX:+PrintGCDetails SwingSet2.jar,屏幕输出如下(节选)
[GC [DefNew: 3968K->64K(4032K), 0.0923407 secs] 3968K->2025K(32704K), 0.0931870 secs]
[GC [DefNew: 4021K->64K(4032K), 0.0356847 secs] 5983K->2347K(32704K), 0.0365441 secs]
[GC [DefNew: 3995K->39K(4032K), 0.0090603 secs] 6279K->2372K(32704K), 0.0093377 secs]
[GC [DefNew: 3992K->23K(4032K), 0.0057540 secs] 6325K->2356K(32704K), 0.0060290 secs]
[GC [DefNew: 3984K->27K(4032K), 0.0013058 secs] 6317K->2360K(32704K), 0.0015888 secs]
[GC [DefNew: 3981K->59K(4032K), 0.0023307 secs] 6315K->2422K(32704K), 0.0026091 secs]
将程序体制并将Young Generation的大小设置为8M,即执行java -jar -verbose:gc -Xmn8m -Xms32m -Xmx32m -XX:+PrintGCDetails SwingSet2.jar,屏幕输出如下(节选)
[GC [DefNew: 7808K->192K(8000K), 0.1016784 secs] 7808K->2357K(32576K), 0.1022834 secs]
[GC [DefNew: 8000K->70K(8000K), 0.0149659 secs] 10165K->2413K(32576K), 0.0152557 secs]
[GC [DefNew: 7853K->59K(8000K), 0.0069122 secs] 10196K->2403K(32576K), 0.0071843 secs]
[GC [DefNew: 7867K->171K(8000K), 0.0075745 secs] 10211K->2681K(32576K), 0.0078376 secs]
[GC [DefNew: 7970K->192K(8000K), 0.0201353 secs] 10480K->2923K(32576K), 0.0206867 secs]
[GC [DefNew: 7979K->30K(8000K), 0.1787079 secs] 10735K->4824K(32576K), 0.1790065 secs]
那 么根据GC输出的信息(这里取第一行)做一下Minor收集的比较。可以看出两次的Minor收集分别在Young generation中找回3904K(3968K->64K)和7616K(7808K->192K)而对于整个jvm则找回 1943K(3968K->2025)和5451K(7808K->2357K)。第一种情况下Minor收集了大约50% (1943/3904)的对象,而另外的50%的对象则被移到了tenured generation。在第二中情况下Minor收集了大约72%的对象,只有不到30%的对象被移到了Tenured Generation.这个例子说明此应用在的Young generation 设置为4m时显的偏小。
提示:一般的Young Generation的大小是整个Heap size的1/4。Young generation的minor收集率应一般在70%以上。当然在实际的应用中需要根据具体情况进行调整。

例3:Young Generation对应用响应的影响
还是使用-Xmn4m 和-Xmn8m进行比较,先执行下面的命令

java -jar -verbose:gc -Xmn4m -Xms32m -Xmx32m -XX:+PrintGCDetails -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime SwingSet2.jar
屏幕输出如下(节选)
Application time: 0.5114944 seconds
[GC [DefNew: 3968K->64K(4032K), 0.0823952 secs] 3968K->2023K(32704K), 0.0827626 secs]
Total time for which application threads were stopped: 0.0839428 seconds
Application time: 0.9871271 seconds
[GC [DefNew: 4020K->64K(4032K), 0.0412448 secs] 5979K->2374K(32704K), 0.0415248 secs]
Total time for which application threads were stopped: 0.0464380 seconds
Young Generation 的Minor收集占用的时间可以计算如下:应用线程被中断的总时常/(应用执行总时?L+应用线程被中断的总时常),那么在本例中垃圾收集占用的时?L约 为系统的5%~14%。那么当垃圾收集占用的时间的比例越大的时候,系统的响应将越慢。
提示:对于互联网应用系统的响应稍微慢一些,用户是可以接受的,但是对于GUI类型的应用响应速度慢将会给用户带来非常不好的体验。

例4:如何决定Tenured Generation 的大小
分别以-Xmn8m -Xmx32m和-Xmn8m -Xmx64m进行对比,先执行
java -verbose:gc -Xmn8m -Xmx32m-XX:+PririntGCDetails -XX:+PrintGCTimeStamps java类,命令行将提示(只提取了Major收集)

111.042: [GC 111.042: [DefNew: 8128K->8128K(8128K), 0.0000505 secs]111.042: [Tenured: 18154K->2311K(24576K), 0.1290354 secs] 26282K->2311K(32704K), 0.1293306 secs]
122.463: [GC 122.463: [DefNew: 8128K->8128K(8128K), 0.0000560 secs]122.463: [Tenured: 18630K->2366K(24576K), 0.1322560 secs] 26758K->2366K(32704K), 0.1325284 secs]
133.896: [GC 133.897: [DefNew: 8128K->8128K(8128K), 0.0000443 secs]133.897: [Tenured: 18240K->2573K(24576K), 0.1340199 secs] 26368K->2573K(32704K), 0.1343218 secs]
144.112: [GC 144.112: [DefNew: 8128K->8128K(8128K), 0.0000544 secs]144.112: [Tenured: 16564K->2304K(24576K), 0.1246831 secs] 24692K->2304K(32704K), 0.1249602 secs]
再执行java -verbose:gc -Xmn8m -Xmx64m-XX:+PririntGCDetails -XX:+PrintGCTimeStamps java类,命令行将提示(只提取了Major收集)
90.597: [GC 90.597: [DefNew: 8128K->8128K(8128K), 0.0000542 secs]90.597: [Tenured: 49841K->5141K(57344K), 0.2129882 secs] 57969K->5141K(65472K), 0.2133274 secs]
120.899: [GC 120.899: [DefNew: 8128K->8128K(8128K), 0.0000550 secs]120.899: [Tenured: 50384K->2430K(57344K), 0.2216590 secs] 58512K->2430K(65472K), 0.2219384 secs]
153.968: [GC 153.968: [DefNew: 8128K->8128K(8128K), 0.0000511 secs]153.968: [Tenured: 51164K->2309K(57344K), 0.2193906 secs] 59292K->2309K(65472K), 0.2196372 secs]
可以看出在Heap size 为32m的时候系统等候时间约为0.13秒左右,而设置为64m的时候等候时间则增大到0.22秒左右了。但是在32m的时候系统的Major收集间隔为 10秒左右,而Heap size 增加到64m的时候为30秒。那么应用在运行的时候是选择32m还是64m呢?如果应用是web类型(即要求有大的吞吐量)的应用则使用64m(即 heapsize大一些)的比较好。对于要求实时响应要求较高的场合(例如GUI型的应用)则使用32m比较好一些。
注意:
1。因为在JVM5运行时已经对Heap-size进行了优化,所以在能确定java应用运行时不会超过默认的Heap size的情况下建议不要对这些值进行修改。
2。 Heap size的 -Xms -Xmn 设置不要超出物理内存的大小。否则会提示“Error occurred during initialization of VM Could not reserve enough space for object heap”。

例5:如何缩短minor收集的时间
下面比较一下采用-XX:+UseParNewGC选项和不采用它的时候的minor收集将有什么不同。先执行
java -jar -server -verbose:gc -Xmn8m -Xms32m -Xmx32m SwingSet2.jar
系统将输出如下信息(片段〕
[GC 7807K->2641K(32576K), 0.0676654 secs]
[GC 10436K->3108K(32576K), 0.0245328 secs]
[GC 10913K->3176K(32576K), 0.0072865 secs]
[GC 10905K->4097K(32576K), 0.0223928 secs]
之后再执行 java -jar -server -verbose:gc -XX:+UseParNewGC -Xmn8m -Xms32m -Xmx32m SwingSet2.jar
系统将输出如下信息(片段〕
[ParNew 7808K->2656K(32576K), 0.0447687 secs]
[ParNew 10441K->3143K(32576K), 0.0179422 secs]
[ParNew 10951K->3177K(32576K), 0.0031914 secs]
[ParNew 10985K->3867K(32576K), 0.0154991 secs]
很显然使用了-XX:+UseParNewGC选项的minor收集的时间要比不使用的时候优。

例6:如何缩短major收集的时间
下面比较一下采用-XX:+UseConcMarkSweepGC选项和不采用它的时候的major收集将有什么不同。先执行
java -jar -verbose:gc -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -Xmn64m -Xms256m -Xmx256m SwingSet2.jar
系统将输出如下信息(片段〕
[Full GC 22972K->18690K(262080K), 0.2326676 secs]
[Full GC 18690K->18690K(262080K), 0.1701866 secs
之后再执行 java -jar -verbose:gc -XX:+UseParNewGC -Xmn64m -Xms256m -Xmx256m SwingSet2.jar
系统将输出如下信息(片段〕
[Full GC 56048K->18869K(260224K), 0.3104852 secs]
提示:此选项在Heap Size 比较大而且Major收集时间较长的情况下使用更合适。

例7:关于-server选项 在JVM中将运行中的类认定为server-class的时候使用此选项。SUN 的Hot Spot JVM5 如果判断到系统的配置满足如下条件则自动将运行的类认定为server-class,并且会自动设置jvm的选项(当没有手工设置这选项的时候〕而且 HOTSPOT JVM5提供了自动调优的功能,他会根据JVM的运行情况进行调整。如果没有特别的需要是不需要太多的人工干预的。SUN形象的称这个机制为“人体工学 ”(Ergonomics〕。具体可以参考http://java.sun.com/docs/hotspot/gc5.0/ergo5.html
*.具有2个或更多个物理的处理器
*.具有2G或者更多的物理内存
提示:此选项要放在所有选项的前面。例如:java -server 其他选项 java类

附录A:预备知识
JVM中对象的划分及管理

JVM根据运行于其中的对象的生存时间大致的分为3种。并且将这3种不同的对象分别存放在JVM从系统分配到的不同的内存空间。这种对象存放空间的管理方式叫做Generation管理方式。
1。Young Generation:用于存放“早逝”对象(即瞬时对象)。例如:在创建对象时或者调用方法时使用的临时对象或局部变量。
2。Tenured Generation:用于存放“驻留”对象(即较长时间被引用的对象)。往往体现为一个大型程序中的全局对象或长时间被使用的对象。
3。Perm Generation:用于存放“永久”对象。这些对象管理着运行于JVM中的类和方法。

JVM选项的分类

JVM有这么几种选项供使用.
1.供-X选项使用的项目,又称为非标准选项,不同厂商的此类型选项是有所不同的。例如:IBM的JVM用的一些选项在Sun的JVM中就不一定能生效。这种选项的使用方式如下:
java -Xmn16m -Xms64m -Xmx64m java类名
2.供-XX选项使用的项目,这种类型的选项可能要求有对系统信息访问的权限。所以要慎用。这种选项的使用方式如下:
java -XX:MaxHeapFreeRatio=70 -XX:+PrintGCDetails java类名
3.java选项(即在命令行执行java后提示的选项).
java -server -verbose:gc -d64 java类名

垃圾收集分类

在JVM中有两种垃圾方式,一种叫做Minor(次收集),另一种叫做Major(主收集)。其中Minor在Young Generation的空间被对象全部占用后执行,主要是对Young Generation中的对象进行垃圾收集。而Major是针对于整个Heap size的垃圾收集。其中Minor方式的收集经常发生,并且Minor收集所占用的系统时间小。Major方式的垃圾收集则是一种“昂贵”的垃圾收集方 式,因为在Major要对整个Heap size进行垃圾收集,这会使得应用停顿的时间变得较长。

GC信息的格式

[GC [<collector>: <starting occupancy1> -> <ending occupancy1>, <pause time1> secs] <starting occupancy3> -> <ending occupancy3>, <pause time3> secs]
<collector> GC为minor收集过程中使用的垃圾收集器起的内部名称.
<starting occupancy1> young generation 在进行垃圾收集前被对象使用的存储空间.
<ending occupancy1> young generation 在进行垃圾收集后被对象使用的存储空间
<pause time1> minor收集使应用暂停的时间长短(秒)
<starting occupancy3> 整个堆(Heap Size)在进行垃圾收集前被对象使用的存储空间
<ending occupancy3> 整个堆(Heap Size)在进行垃圾收集后被对象使用的存储空间
<pause time3> 整个垃圾收集使应用暂停的时间长短(秒),包括major收集使应用暂停的时间(如果发生了major收集).
GC信息的选项
-XX:+PrintGCDetails 显示GC的详细信息
-XX:+PrintGCApplicationConcurrentTime 打印应用执行的时间
-XX:+PrintGCApplicationStoppedTime 打印应用被暂停的时间
提示:1.":"后的"+"号表示开启此选项,如果是"-"号那么表示关闭此选项。
2.在不同的选项和不同的收集方式和类型下输出的格式会有所不同。

分享到:
评论
1 楼 deyimsf 2012-01-20  
java -verbose:gc -Xmn8m -Xmx64m-XX:+PririntGCDetails -XX:+PrintGCTimeStamps java类

请问为什么说上面的配置只提取了Major收集,这种配置不会打印minor gc 吗

相关推荐

    GC2053_1,2.9"GC2053sensor_格科微_GC2053_gc2053datasheet_galaxycore_

    《GC2053:格科微电子的1/2.9" FHD CMOS图像传感器解析》 在现代科技的快速发展中,图像传感器在各个领域都扮演着至关重要的角色,尤其是在摄像头应用中。GC2053是格科微电子(GalaxyCore)推出的一款1/2.9英寸的高...

    SENSOR_GC1054.rar_1054-sensor_SENSOR_GC1054_gc1054

    标题中的"SENSOR_GC1054.rar_1054-sensor_SENSOR_GC1054_gc1054"暗示了我们正在处理一种名为GC1054的传感器,这可能是一款专用于图像处理的传感器。在IT行业中,这类传感器通常被应用于摄像头设备、机器视觉系统或...

    GC6153_SERIAL_GC6153

    标题 "GC6153_SERIAL_GC6153" 指向的是一款基于MTK(MediaTek)平台的驱动程序,专为控制SPI接口的GC6153芯片而设计。这款驱动程序的主要功能是确保GC6153芯片在系统中能够正确地被初始化、配置和操作,从而实现其...

    gc2145 datasheet

    GC2145 CMOS图像传感器数据手册 GC2145是一种1/5英寸的UXGA CMOS图像传感器,用于图像采集和处理应用场景。下面是GC2145数据手册的详细解读: Sensor Overview GC2145是一种高性能的CMOS图像传感器,具有高分辨率...

    gc4023 datasheet

    GC4023 CMOS图像传感器数据手册 GC4023是一款高性能的CMOS图像传感器,用于capturing高质量图像。该传感器具有1/2.7英寸的感光面积、4Mega像素的高分辨率和低噪音的特点。该传感器的datasheet提供了详细的技术规格...

    MT6261_GC6153_Driver_V0_格科微gc61538w_GC6153_格科微_格科微GC6153@_mt6261

    《MT6261_GC6153_Driver_V0:格科微GC6153模组驱动解析》 在电子技术领域,驱动程序扮演着至关重要的角色,它是硬件设备与操作系统之间的桥梁,使得软件能够有效控制硬件设备。本文将深入探讨"MT6261_GC6153_Driver...

    gc02m1 datasheet

    GC02M1 datasheet GC02M1是一款CMOS图像传感器,具有高分辨率、低噪声和高灵敏度等特点。下面是根据GC02M1 datasheet的内容生成的相关知识点: 1. 传感器概述 GC02M1是一款1/5英寸的CMOS图像传感器,具有200万像素...

    MT65xx_GC032A_Driver_20170614_GC032A_GC032A_Drive

    《MT65xx_GC032A_Driver_20170614_GC032A_GC032A_Drive》是一款专为MT65xx平台设计的GC032A图像传感器驱动程序,它在原有的厂家驱动基础上进行了一些定制化的改进,以优化性能和效果。此驱动程序的更新日期为2017年6...

    gc2145_bpi_a64_android验证完成_改全部的ov5640为gc2145_20170524_1113没有外层目录.7z

    在全志A64平台点亮GC2145 2017/5/25 14:39 小技巧,直接在全志A64的SDK中搜索ov5640(默认是几乎通的),全部替换为gc2145即可。 1、 R:\wyb\gc2145_bpi_a64_android\android\device\softwinner\bpi-m64-lcd\...

    GC5025.tar.gz_RK camera_camera_gc5025 RK3368_gc5025驱动_rk摄像头驱动

    《GC5025.tar.gz:RK3368平台上的GC5025摄像头驱动详解》 在嵌入式系统开发中,摄像头驱动扮演着至关重要的角色,它连接硬件设备与软件应用,使得图像捕获和处理成为可能。本文将深入探讨针对RK3368平台的GC5025...

    gc2355_mipi_raw_摄像头gc2355驱动_

    【标题】"gc2355_mipi_raw_摄像头gc2355驱动_" 指的是一个针对特定型号摄像头GC2355的驱动程序,该驱动是为MT6737处理器平台设计的。在嵌入式系统中,摄像头驱动是连接硬件设备(即摄像头)与操作系统内核之间的重要...

    GC-powerstation 9.1.2

    "GC-powerstation 9.1.2" 是一个专门针对垃圾收集(Garbage Collection, GC)优化的工具或平台的版本号。在IT领域,尤其是Java编程语言中,垃圾收集是一个核心概念,它负责自动管理内存,释放不再使用的对象,以防止...

    GC0329 datasheet

    ### GC0329 CMOS 图像传感器技术详解 #### 一、传感器概述 ##### 1.1 一般描述 GC0329是一款由国内最大的CMOS图像传感器制造商格科微电子研发的新一代VGA图像传感器。该传感器拥有640×480像素的分辨率,采用1/9...

    GC2035 DataSheet

    GC2035是一款高品质的200万像素CMOS图像传感器,主要应用于移动电话摄像头和数码相机产品。该传感器具备1/5英寸的标准光学格式、1616Vx1232H的像素阵列,并且内部集成了10位模数转换器(ADC)以及图像信号处理器。...

    gc0310 前置摄像头驱动

    【gc0310前置摄像头驱动】是针对高通(Qualcomm)平台,特别是msm8909芯片组的一款摄像头驱动程序。该驱动是为了使gc0310这款图像传感器在搭载高通骁龙处理器的设备上正常工作,确保前置摄像头功能的稳定性和效率。...

    visualgc插件离线安装包

    《VisualGC插件:JVM监控的得力助手》 在Java开发中,对JVM(Java虚拟机)的监控是至关重要的,它可以帮助我们理解应用程序的运行状况,优化性能,预防内存泄漏等问题。VisualVM是一款强大的JVM诊断工具,它提供了...

    gc0310 mipi 驱动

    【标题】"gc0310 mipi 驱动"是针对Android 4.4系统,基于MediaTek MT6572平台的一款摄像头驱动程序。MIP(Mobile Industry Processor Interface)I是移动设备中广泛使用的高速接口,主要用于连接摄像头传感器和其他...

    GC2023 DataSheet

    GC2023是一款高性价比的2M像素CMOS图像传感器,主要用于手机相机和数码相机产品。GC2023采用了1928H x 1088V像素阵列,集成了片上10位模数转换器(ADC)和图像信号处理器。其高性能与低功耗功能的全面集成,使其成为...

    2019gc2000.rar

    《GC-PowerStation 2019中文版:SMT导坐标与GERBER文件处理详解》 GC-PowerStation是一款专业且功能强大的电子制造软件,主要用于SMT(表面贴装技术)工艺中的导坐标和GERBER文件处理。该软件以其高效、精准的特性...

Global site tag (gtag.js) - Google Analytics