java.lang.OutOfMemoryError的产死及措置要收 - 青山一

来源:互联网 发布:usb网络共享驱动 编辑:程序博客网 时间:2024/04/28 02:40
最强弃少
这里以tomcat情形为例,其它WEB处事器如jboss,weblogic等是同一个事理。
1、java.lang.OutOfMemoryError: PermGen space

PermGen space的全称是Permanent Generation space,是指内存的永久生活生活地区,
这块内存首要是被JVM存放Class战Meta信息的,Class正在被Loader时就会被放到PermGen space中,
它战存放类实例(Instance)的Heap地区不同,GC(Garbage Collection)不会正在主法式运转期对
PermGen space进止清算,所以若是你的运用中有很多CLASS的话,就很可以或许显现PermGen space漏洞,
这类漏洞常睹正在web处事器对JSP进止pre compile的时分。若是你的WEB APP下都用了大年夜量的第三方jar, 其巨细
超越了jvm默许的巨细(4M)那么就会收生此漏洞信息了。
处理要收: 手动设置MaxPermSize巨细

点窜TOMCAT_HOME/bin/catalina.sh
正在“echo "Using CATALINA_BASE:   $CATALINA_BASE"”上里插足以下止:
JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m
倡议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以或许到达削减jar 文档重复占用内存的方针。

2、java.lang.OutOfMemoryError: Java heap space
Heap size 设置
JVM堆的设置是指java法式运转过程当中JVM可以或许调配运用的内存空间的设置.JVM正在启动的时分会自动设置Heap size的值,
其初始空间(即-Xms)是物理内存的1/64,最大年夜空间(-Xmx)是物理内存的1/4。可以或许支配JVM供给的-Xmn -Xms -Xmx等选项可
进止设置。Heap size 的巨细是Young Generation 战Tenured Generaion 之战。
提示:正在JVM中若是98%的时候是用于GC且可用的Heap size 不足2%的时分将扔出此同常信息。
提示:Heap Size 最大年夜不要超越可用物理内存的80%,普通的要将-Xms战-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。
处理要收:手动设置Heap size
点窜TOMCAT_HOME/bin/catalina.sh
正在“echo "Using CATALINA_BASE:   $CATALINA_BASE"”上里插足以下止:
JAVA_OPTS="-server -Xms800m -Xmx800m   -XX:MaxNewSize=256m"

3、实例,以下给出1G内存情形下java jvm 的参数设置参考:

JAVA_OPTS="-server -Xms800m -Xmx800m  -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "

四 相闭材料

Java捏造机的选项

Mac OS X的Java捏造机除具有尺度的HotSpot捏造机的选项之外,还支撑很多非尺度的选项(-X战-XX),本章列出了这些选项以及一些值得留意的例外事项。

请留意: 除非特别声明,不然正在一个选项中指定的bytes(字节)都是做为参数。您也可以或许或许分辩经过k或者m这两个字母来指定千个字节或者兆个字节(巨细写都可以或许)。例如,下里的几种形式都是默示字节数:4194301,4096k,4096K,4m,战4M。

普通选项
-server
正在Mac OS X中没有特另外处事器捏造机(server VM)。正在激活java的时分可以或许运用 -server 选项,但这实在不是启动另外的捏造机,它仍是启动客户捏造机(client VM),只是这个捏造机针对处事器的运用情形进止了调优。这些调优包括:
  • 正在共享档案的生成过程当中运用不同的类列表,这个列表中不包括GUI类(睹“Mac OS X的Java共享档案”部分)。
  • 增加Java堆的尺寸。
  • 增加Eden代的内存空间的尺寸。
  • 翻开线程确当地Eden垃圾支散器(garbage collection)。

-X
隐现一个非尺度捏造机选项的扼要描述。
-Xbootclasspath:path
指定一个目录以及JAR战ZIP档案的列表,做为搜刮启动类的范围。列表中各项之间的分隔符为冒号(:)。
-Xfuture
对类文件施止严格的把戏查抄。这个选项强迫Java对是不是遵守类文件规范做更加严格的查抄,而缺省的查抄只是基于Java 1.1.x的尺度。您应当运用这个选项来对代码进止测试,以便确保这些代码正在将来的Java版本中可以或许工做,这些将来的版本可以或许强迫进止加倍严格的类文件把戏查抄。
-Xprof
把运转法式详细的止为阐发数据进出给尺度输出。正在产等第的代码中不克不及运用这个选项。
-Xrs
-XX:+ReduceSignalUsage选项一样。
-XX:+ReduceSignalUsage
正常状态下,Java响应SIGHUPSIGINT,SIGTERM旌旗暗记。若是指定了这个选项,则Java会轻忽这些旌旗暗记,您要凭据具体的需要正在当地代码中实现这些旌旗暗记的处理函数,同时还要正在System.exit()中实现相闭的封闭例程。
-XX:ReservedCodeCacheSize=size in bytes
设置最大年夜的代码缓存的巨细,缺省状态下是32(32M)。
-XX:-PrintJavaStackAtFatalState
缺省状态下,铛铛地代码解体时,Java会收生回溯(backtraces)信息。若是您正在Java的漏洞报告中看到认识体的信息,则可以或许把这个选项封闭。
Mac OS X 专用选项
-Xdock:name=applicationName
设定运用法式正在Dock战菜单条上隐现的名称。若是这个选项没有被设定,则缺省状态下Mac OS X会隐现主类的全名。您只需要对那些从号令止或者JAR文件中启动的法式设定这个选项,那些可以或许双击的运用法式包则从Info.plist文件中读取正确的隐现名。
-XX:+UseFileLocking
这个选项用来激活Carbon文件的锁定功能,缺省状态下封闭。若是您的Java运用法式战一些文件彼此做用,而这些文件同时又遭到一些Carbon运用法式的影响,则您需要运用这个选项,它可以或许提防运用法式点窜那些正正在被另外法式拜候的文件。
堆的尺寸
-Xmssize in bytes
设定Java堆的初始尺寸,缺省尺寸是2097152 (2MB)。这个值必须是1024个字节(1KB)的倍数,且比它大年夜。(-server选项把缺省尺寸增加到32M。)
-Xmnsize in bytes
为Eden工具设定初始Java堆的巨细,缺省值为640K。(-server选项把缺省尺寸增加到2M。)
-Xmxsize in bytes
设定Java堆的最大年夜尺寸,缺省值为64M,(-server选项把缺省尺寸增加到128M。) 最大年夜的堆尺寸到达将远2GB(2048MB)。

请留意:很多垃圾支散器的选项依好过堆巨细的设定。请正在微调垃圾支散器运用内存空间的体例之前,确认是不是曾正确设定了堆的尺寸。

垃圾支散:内存的运用
-XX:MinHeapFreeRatio=percentage as a whole number
点窜垃圾回支以后堆中可用内存的最小百分比,缺省值是40。若是垃圾回支后最少还有40%的堆内存没有被释放,则系统将增加堆的尺寸。
-XX:MaxHeapFreeRatio=percentage as a whole number
改变垃圾回支以后战堆内存缩小之前可用堆内存的最大年夜百分比,缺省值为70。这意味着若是正在垃圾回支以后还有大年夜于70%的堆内存,则系统就会削减堆的尺寸。
-XX:NewSize=size in bytes
为已分拨内存的工具中的Eden代设置缺省的内存尺寸。它的缺省值是640K。(-server选项把缺省尺寸增加到2M。)
-XX:MaxNewSize=size in bytes
答理您改变初期工具空间的上限,新建工具所需的内存就是从这个空间平分拨来的,这个选项的缺省值是640K。(-server选项把缺省尺寸增加到2M。)
-XX:NewRatio=value
改变新旧空间的尺寸比例,这个比例的缺省值是8,意思是新空间的尺寸是旧空间的1/8。
-XX:SurvivorRatio=number
改变Eden工具空间战残余空间的尺寸比例,这个比例的缺省值是10,意思是Eden工具空间的尺寸比残余空间大年夜survivorRatio+2倍。
-XX:TargetSurvivorRatio=percentage
设定您所期视的空间提取后被运用的残余空间的百分比,缺省值是50。
-XX:MaxPermSize=size in MB
长久代(permanent generation)的尺寸,缺省值为32(32MB)。
垃圾支散: 普通设定
-Xincgc
Mac OS X不支撑这个选项,不支撑这类操演式的垃圾支散器。
-Xnoclassgc
禁用类的垃圾支散。
-XX:+UseConcMarkSweepGC
激活标识表记标帜战消除同时进止的垃圾支散举动,这个选项对多处理器的计算机有效。
-XX:+UseParallelGC
激活并止的垃圾支散举动,这个选项只对多处理器的计算机有效。
-XX:-DisableExplicitGC
轻忽代码中对System.gc()的隐式挪用。捏造机如故依照正常的机造进止垃圾支散。这个选项禁止正在代码中强迫施止垃圾支散。
-XX:+PrintTenuringDistribution
打印初期代中已分拨内存的工具占用内存时候的信息。
编译
-Xint
只正在诠释(interperated)模式下运转捏造机。若是运用这个选项,系统将不编译任何字节码。
-XX:CompileThreshold=value
正在编译进手下手前改变要收挪用(法式分支)的数量,缺省值是1000。
-XX:-InlineUnreachableCalls
缺省状态下,捏造机对所有可以或许的代码进止要收内联处理(method inlining),以便利编译器进止优化。对这个选项进止设定会使较少的代码依照内联要收被编译。这样,那些正常状态下不会运转的代码,如例外处理,就不会被处理为内联代码,而只能正在运转时进止诠释。设定这个选项可以或许会大年夜大年夜降落性能。
-XX:+CITime
隐现有几时候花正在编译过的代码上。
-XX:+PrintCompilation
正在Java的要收被编译时,打印其的跟踪信息。
Threading
-XX:NewSizeThreadIncrease=size in KB
答理您指定每个举动线程会增加几初期工具空间。这个选项正在调度由于线程增加而增加的分拨率时可以或许会有效。它的缺省值为16(16 kilobytes)。
-XX:ThreadStackSize=size in KB
改变线程栈的巨细。缺省状态下,线程栈的巨细就是操做系统所运用的栈的缺省巨细。
-XX:+UseTLAB
激活线程当地的分拨缓冲区。 运用这个缓冲区将使线程任务沉重的运用法式的内存分拨更加具有可扩大性,大年夜大年夜提高内存分拨的性能。这个选项正在多处理器的计算机战Mac OS X Server上缺省翻开。
共享
-XX:+PrintSharedSpace
翻开共享的冗少输出。
-XX:-UseSharedSpaces
封闭共享。
JVM垃圾回支机造正在PDM系统中的运用

1.JVM的gc概述
   
    gc即垃圾支散机造是指jvm用于释放那些不再运用的工具所占用的内存。java言语实在不要求jvm有gc,也没有规定gc如何工做。不过经常利用的jvm都有gc,并且大年夜大年夜都gc都运用近似的算法打点内存战施止支散操做。
   
    正在充实分明了垃圾支散算法战施止过程后,才气有效的优化它的性能。有些垃圾支散专用于特另外运用法式。比如,及时运用法式首要是为了提防垃圾支散中止,而大年夜大年夜都OLTP运用法式则重视团体从命。分明了运用法式的工做负荷战jvm支撑的垃圾支散算法,即可以或许进止优化设置设备摆设垃圾支散器。
   
    垃圾支散的方针正在于消除不再运用的工具。gc经过确定工具是不是被举开工具援引来确定是不是支散该工具。gc尾先要鉴定该工具是不是是时分可以或许支散。两种经常利用的要收是援引计数战工具援引遍历。
   
    1.1.援引计数
    援引计数存储对特定工具的所有援引数,也就是道,当运用法式创坐援引以及援引超越范围时,jvm必须适合增减援引数。当某工具的援引数为0时,即可以或许进止垃圾支散。
   
    1.2.工具援引遍历
    初期的jvm运用援引计数,现正在大年夜大年夜都jvm采用工具援引遍历。工具援引遍历从一组工具进手下手,沿着全部工具图上的每条链接,递回确定可到达(reachable)的工具。若是某工具不克不及从这些根工具的一个(最少一个)到达,则将它做为垃圾支散。正在工具遍历阶段,gc必须记着哪些工具可以或许到达,以便删除不止到达的工具,这称为标识表记标帜(marking)工具。
   
    下一步,gc要删除不止到达的工具。删除时,有些gc只是简单的扫描货仓旅店,删除未标识表记标帜的未标识表记标帜的工具,并释放它们的内存以生成新的工具,这叫做消除(sweeping)。这类要收的成绩正在于内存会分成好多小段,而它们不足以用于新的工具,可是组开起来却很大年夜。因此,很多gc可以或许从头构造内存中的工具,并进止压缩(compact),构成可支配的空间。
   
    为此,gc需要终止其他的举动举动。这类要收意味着所有与运用法式相闭的工做终止,只有gc运转。成效,正在响应期间增减了很多稠浊要求。另外,更复杂的 gc接绝增加或同时运转以削减或者消除运用法式的中止。有的gc运用单线程完成这项工做,有的则采用多线程以增加从命。
   
    2.几种垃圾回支机造
   
    2.1.标识表记标帜-消除支散器
    这类支散器尾先遍历工具图并标识表记标帜可到达的工具,然后扫描货仓旅店以寻觅未标识表记标帜工具并释放它们的内存。这类支散器普通运用单线程工做并终止其他操做。
   
    2.2.标识表记标帜-压缩支散器
    有时也叫标识表记标帜-消除-压缩支散器,与标识表记标帜-消除支散器有相同的标识表记标帜阶段。正在第两阶段,则把标识表记标帜工具复造到货仓旅店的新域中以便压缩货仓旅店。这类支散器也终止其他操做。
   
    2.3.复造支散器
    这类支散器将货仓旅店分为两个域,常称为半空间。每次仅运用一半的空间,jvm生成的新工具则放正在另外一半空间中。gc运转时,它把可到达工具复造到另外一半空间,从而压缩了货仓旅店。这类要收开用于短生活生活期的工具,连绝复造少生活生活期的工具则招致从命降落。
   
    2.4.增量支散器
    增量支散器把货仓旅店分为多个域,每次仅从一个域支散垃圾。这会造成较小的运用法式中止。
   
    2.5.分代支散器
    这类支散器把货仓旅店分为两个或多个域,用以存放不同寿命的工具。jvm生成的新工具普通放正在此中的某个域中。过一段时候,继绝存正在的工具将获得运用期并转进更少寿命的域中。分代支散器对不同的域运用不同的算法以优化性能。
   
    2.6.并进出散器
    并进出散器与运用法式同时运转。这些支散器正在某点上(比如压缩时)普通都不得接绝止其他操做以完成特定的任务,可是由于其他运用法式可进止其他的布景操做,所以中止其他处理的现实时候大年夜大年夜降落。
   
    2.7.并止支散器
    并止支散器运用某种传统的算法并运用多线程并止的施止它们的工做。正在多cpu呆板上运用多线程技术可以或许隐著的提高java运用法式的可扩大性。
   
    3.Sun HotSpot 1.4.1 JVM堆巨细的调剂
   
    Sun HotSpot 1.4.1运用分代支散器,它把堆分为三个首要的域:新域、旧域以及永久域。Jvm生成的所有新工具放正在新域中。一旦工具经历了肯定命目的垃圾支散循环后,便获得运用期并进进旧域。正在永久域中jvm则存储class战method工具。就设置设备摆设而言,永久域是一个独坐域并且不觉得是堆的一部分。
   
    下里先容如何控造这些域的巨细。可运用-Xms战-Xmx 控造全部堆的本始巨细或最大年夜值。
    下里的号令是把初始巨细设置为128M:
    java –Xms128m
    –Xmx256m为控造新域的巨细,可运用-XX:NewRatio设置新域正在堆中所占的比例。
   
    下里的号令把全部堆设置成128m,新域比率设置成3,即新域与旧域比例为1:3,新域为堆的1/4或32M:
    java –Xms128m –Xmx128m
    –XX:NewRatio =3可运用-XX:NewSize战-XX:MaxNewsize设置新域的初始值战最大年夜值。
   
    下里的号令把新域的初始值战最大年夜值设置成64m:
    java –Xms256m –Xmx256m –Xmn64m
    永久域默许巨细为4m。运转法式时,jvm会调剂永久域的巨细以满足需要。每次调剂时,jvm会对堆进止一次完全的垃圾支散。
   
    运用-XX:MaxPerSize标识表记标帜来增加永久域搭巨细。正在WebLogic Server运用法式加载较多类时,经常需要增加永久域的最大年夜值。当jvm加载类时,永久域中的工具慢剧增加,从而使jvm接绝调剂永久域巨细。为了提防调剂,可运用-XX:PerSize标识表记标帜设置初始值。
    下里把永久域初始值设置成32m,最大年夜值设置成64m。
    java -Xms512m -Xmx512m -Xmn128m -XX:PermSize=32m -XX:MaxPermSize=64m
   
    默许状态下,HotSpot正在新域中运用复造支散器。该域普通分为三个部分。第一部分为Eden,用于生成新的工具。另两部分称为救援空间,当Eden布满时,支散器终止运用法式,把所有可到达工具复造到当前的from救援空间,一旦当前的from救援空间布满,支散器则把可到达工具复造到当前的to救援空间。From战to救援空间互换角色。维持举动的工具将正在救援空间接绝复造,直到它们获得运用期并转进旧域。运用-XX:SurvivorRatio可控造新域子空间的巨细。
   
    同NewRation一样,SurvivorRation规定某救援域与Eden空间的比值。比如,以下号令把新域设置成64m,Eden占32m,每个救援域各占16m:
    java -Xms256m -Xmx256m -Xmn64m -XX:SurvivorRation =2
   
    如前所述,默许状态下HotSpot对新域运用复造支散器,对旧域运用标识表记标帜-消除-压缩支散器。正在新域中运用复造支散器有很多意义,由于运用法式生成的大年夜部合作具是短折命的。梦想状态下,所有过渡工具正在移出Eden空间时将被支散。若是可以或许这样的话,并且移出Eden空间的工具是少寿命的,那么理论上可以或许坐即把它们移进旧域,提防正在救援空间重复复造。可是,运用法式不克不及开适这类梦想状态,由于它们有一小部分中少寿命的工具。最好是连结这些中少寿命的工具并放正在新域中,由于复造小部分的工具总比压缩旧域便宜。为控造新域中工具的复造,可用-XX:TargetSurvivorRatio控造救援空间的比例(该值是设置救援空间的运用比例。如救援空间位1M,该值50默示可用500K)。该值是一个百分比,默许值是50。当较大年夜的货仓旅店运用较低的 sruvivorratio时,应增加该值到80至90,以更好支配救援空间。用-XX:maxtenuring threshold可控造上限。
   
    为放置所有的复造局部收生以及期视工具从eden扩大到旧域,可以或许把MaxTenuring Threshold设置成0。设置完成后,现实上就不再运用救援空间了,因此应把SurvivorRatio设成最大年夜值以最大年夜化Eden空间,设置以下:
    java … -XX:MaxTenuringThreshold=0 –XX:SurvivorRatio=50000 …
   
    4.BEA JRockit JVM的运用
    Bea WebLogic 8.1运用的新的JVM用于Intel平台。正在Bea安拆完毕的目录下可以或许看到有一个近似于jrockit81sp1_141_03的文件夹。这就是 Bea新JVM所正在目录。不同于HotSpot把Java字节码编译成当地码,它预先编译成类。JRockit还供给了更详细的功能用以不雅考察JVM的运转状态,首要是独坐的GUI控造台(只能开用于运用Jrockit才气运用jrockit81sp1_141_03自带的console监控一些cpu及 memory参数)或者WebLogic Server控造台。
   
    Bea JRockit JVM支撑4种垃圾支散器:
    4.1.1.分代复造支散器
    它与默许的分代支散器工做策略近似。工具正在新域平分拨,即JRockit文档中的nursery。这类支散器最开适单cpu机上小型堆操做。
   
    4.1.2.单空间并进出散器
    该支散器运用完全堆,并与布景线程共同工做。固然这类支散器可以或许消除中止,可是支散器需消耗较少的时候寻觅死工具,并且处理运用法式时支散器经常运转。若是处理器不克不及对付运用法式收生的垃圾,它会中止运用法式并封闭支散。
   
    分代并进出散器这类支散器正在照顾***域运用排它复造支散器,正在旧域中则运用并进出散器。由于它比单空间共同收生支散器中止频繁,因此它需要较少的内存,运用法式的运转从命也较下,留意,太小的照顾***域可以或许招致大年夜量的且则工具被扩大到旧域中。这会造成支散器超负荷运做,乃至采用排它性工做体例完成支散。
   
    4.1.3.并止支散器
    该支散器也终止其他过程的工做,但运用多线程以减速支散过程。固然它比其他的支散器易于惹起少时候的中止,但普通能更好的支配内存,法式从命也较下。
   
    默许状态下,JRockit运用分代并进出散器。要改变支散器,可运用-Xgc:<gc_name>,对应四个支散器分辩为gencopy, singlecon,gencon以及parallel。可运用-Xms战-Xmx设置堆的初始巨细战最大年夜值。要设置照顾***域,则运用-Xns:java –jrockit –Xms512m –Xmx512m –Xgc:gencon –Xns128m…固然JRockit支撑-verbose:gc开闭,但它输出的信息会因支散器的不同而同。JRockit还支撑memory、 load战codegen的输出。
   
    留意 :若是 运用JRockit JVM的话还可以或许运用WLS自带的console(C:\bea\jrockit81sp1_141_03\bin下)来监控一些数据,如cpu, memery等。要想能构监控必须正在启动处事时startWeblogic.cmd中插足-Xmanagement参数。
   
    5.如何从JVM中获守信息来进止调剂
   
    -verbose.gc开闭可隐现gc的操做内容。翻开它,可以或许隐现最忙战最空忙支散止为收生的时候、支散前后的内存巨细、支散需要的时候等。翻开- xx:+ print***etails开闭,可以或许详细认识gc中的变革。翻开-XX: + PrintGCTimeStamps开闭,可以或许认识这些垃圾支散收生的时候,自jvm启动当前以秒计量。最后,经过-xx: + PrintHeapAtGC开闭认识堆的更详细的信息。为了认识新域的状态,可以或许经过-XX:=PrintTenuringDistribution开闭认识获得运用期的工具权。
   
    6.Pdm系统JVM调剂
   
    6.1.处事器:条件内存1G 单CPU
   
    可经过以下参数进止调剂:-server 启用处事器模式(若是CPU多,处事器机倡议运用此项)
   
    -Xms,-Xmx普通设为同样巨细。 800m
    -Xmn 是将NewSize与MaxNewSize设为一致。320m
    -XX:PerSize 64m
    -XX:NewSize 320m 此值设大年夜可调大年夜新工具区,削减Full GC次数
    -XX:MaxNewSize 320m
    -XX:NewRato NewSize设了可不设。4
    -XX: SurvivorRatio 4
    -XX:userParNewGC 可用来设置并止支散
    -XX:ParallelGCThreads 可用来增加并止度 4
    -XXUseParallelGC 设置后可以或许运用并止消除支散器
    -XX:UseAdaptiveSizePolicy 与上里一个联开运用效果更好,支配它可以或许自动优化新域巨细以及救援空间比值
   
    6.2.客户机:经过正在JNLP文件中设置参数来调剂客户端JVM
   
    JNLP中参数:initial-heap-size战max-heap-size
   
    这可以或许正在framework的RequestManager中生成JNLP文件时插足上述参数,可是这些值是要求凭据客户机的硬件状态变革的(如客户机的内存巨细等)。倡议这两个参数值设为客户机可用内存的60%(有待测试)。为了正在静态生成JNLP时以上两个参数值可以或许随客户机不同而不同,坚固虑获得客户机系统信息并将这些嵌到尾页index.jsp中做为连接要求的参数。
   
    正在设置了上述参数后可以或许经过Visualgc 来不雅考察垃圾回支的一些参数状态,再做响应的调剂来改善性能。普通的尺度是削减fullgc的次数,最好硬件支撑运用并止垃圾回支(要求多CPU)。

Hot Spot JVM5中的GC调优
引言
有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.正在不同的选项战不同的支散体例战规范下输出的把戏会有所不同。


0 0