gc

infant mortility

年轻代young generation,包括1个eden和2个survivor空间,solaris没有eden。

(有时,大的yg导致minorgc间歇变大,这就是说yg中的对象有足够的时间去死,well-tuned;但是,和应用中的对象生命期分布有关,同样的yg大小却导致其中的对象没时间去死。)

(如何决定参数设置,研究你关注的性能指标对参数值的敏感度,这不废话吗?性能指标有吞吐量throughtput和pause时间, throughtput是用在非垃圾回收上的的时间用在垃圾回收上的时间的比例。)

minor gc

终身代tenured generation

major gc

 永久代permanent generation

-verbose:gc

[GC 325407K->83000K(776768K), 0.2300771 secs] //minor gc,收集前yg325407,收集后83000,堆大小为776768,不含一个survivor,不包括永久代。
  [GC 325816K->83372K(776768K), 0.2454258 secs] //minor gc
  [Full GC 267628K->83769K(776768K), 1.8479984 secs]//major gc

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

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]

收集开使于应用执行了111.042秒,分别收集了年轻代,终身代,还有附加开销等。

-XX:MinHeapFreeRatio=40
-XX:MaxHeapFreeRatio=70
-Xms3m
-Xmx64m

-MaxPermSize
(除非你担心pause时间,应该给足够大的内存,64m太少了;可以把xms和xmx设成一样,使得内存分配有更高的可预测性;64位架构比32位多占内存,多cpu比少cpu分配内存的并发请求更多)

XX:NewRatio=3//yg占1/4,tg占3/4
NewSize
MaxNewSize
-XX:SurvivorRatio=6//survivor空间占yg的1/8
-XX:+PrintTenuringDistribution
(如果看到太多major gc或受不了pause时间,可以给yg更多空间,但是不能接近堆的一半,那样的话你只会有major gc)
(年轻代保证:eden+survivor的live object能拷贝到另一个survivor,但是除了serial collector没有哪个收集器提供这个保证)

-XX:+UseParallelGC//throughtput collector,年轻代并行,终身代同serial collector.
-XX:ParallelGCThreads=<desired number>//单cpu上,throughtput collector的性能还不如serial collector,因为有同步开销等等;但是线程多了,从yg提升到tg也许会带来更多碎片,因为每个线程都预留了一部分tg空间并且分割可用空间为提升缓存,鉴于此,可以减少线程或加大tg;缺省是每个cpu一个线程。
-XX:MaxGCPauseMillis=<nnn>//也有时候达不到这个要求,缺省没这个设置。收集起会统计并调整generation的大小,但是调用System.gc()没有用,会被忽略。如果两个代都达不到要求,先调整时间更大的那个代。
-XX:YoungGenerationSizeIncrement=<nnn >
-XX:TenuredGenerationSizeIncrement=<nnn>
-XX:AdaptiveSizeDecrementScaleFactor=<nnn >
-XX:GCTimeRatio=<nnn>//垃圾回收占总时间的比例:1/(1+nnn),缺省是1%
-XX:+UseConcMarkSweepGC//yg,tg都并行,适用于有交互的,请求低pause时间的应用。收集tg时开始又一次停止initial mark,中间有一次remark,比开始时间长,中间这一次有多个线程在处理。小垃圾回收类似serial collector但是有多个线程。它在并发mark和sweep阶段会使用处理器资源,单cpu平台上fortuitous暂时的,此外它sleep。这个线程要保证tg不能变满,一旦满了就需要停止所有应用线程,来一次回收,这叫做full gc,这是需要调整gc设置的标志,它根据统计信息估计快满的时候启动收集,t-until-full或者根据设置tg用掉多少就开始收集。浮动垃圾,有的对象在回收时是活的,回收结束后死了,这些对象是浮动垃圾,可以在下次回收,tg中应有20%空间放浮动垃圾。
-XX:CMSInitiatingOccupancyFraction=<nn>

  • stop all application threads; do the initial mark; resume all application threads

  • do the concurrent mark (uses one procesor for the concurrent work)

  • do the concurrent pre-clean (uses one processor for the concurrent work)

  • stop all application threads; do the remark; resume all application threads

  • do the concurrent sweep (uses one processor for the concurrent work)

  • do the concurrent reset (uses one processor for the concurrent work)
    一般来说,cms占用cpu直到处理完成,这在cpu少的机器上是个问题,所以有了i-cms,它把收集任务划分成小片,每次小片完成就放弃cpu,给应用程序机会。建议,

    -XX:+UseConcMarkSweepGC \

    -XX:+CMSIncrementalMode \

    -XX:+CMSIncrementalPacing \

    -XX:CMSIncrementalDutyCycleMin=0 \

    -XX:+CMSIncrementalDutyCycle=10 \

    -XX:+PrintGCDetails \

    -XX:+PrintGCTimeStamps \

    -XX:-TraceClassUnloading

    但是,工具过去的统计不一定能够准确预测将来,如果有很多full gc,试试,

  • -XX:CMSIncrementalSafetyFactor=<N>

    -XX:CMSIncrementalDutyCycleMin=<N>

    -XX:-CMSIncrementalPacing -XX:CMSIncrementalDutyCycle=<N>


(serial collector用一个线程回收yg,throughput collector用过多个线程回收yg;如果有很多线程分配对象,就需要更大的yg)

如果没有显式设置堆大小,它会根据系统物理内存计算得出。xms大约是64分之一(DefaultInitialRAMFraction),xmx大约是4分之一(DefaultMaxRAM)
如果花了98%的时间但仅回收了2%的内存会抛出oome。
-XX:+DisableExplicitGC

java -Dsun.rmi.dgc.client.gcInterval=3600000
-Dsun.rmi.dgc.server.gcInterval=3600000 ...
使用rmi的分布式程序会引用别的vm里的对象,必须显式gc收集
-XX:SoftRefLRUPolicyMSPerMB=10000

 

 static object 在哪里,堆里?那它就不能被回收?那还不如用单例!是吗?

 http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html
http://www.oracle.com/technetwork/java/ergo5-140223.html

 

 

posted @ 2014-01-20 15:49  jvava  阅读(329)  评论(0编辑  收藏  举报