On 27.07.2013 22:06, Philippe Mouawad wrote: > Thanks Rainer for explanation. > From your experience with GC would you say adding those 2 options is a good > idea ? > -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled
In general CMS produces shorter pauses but is a bit less efficient (more overhead in terms of CPU). Since it doesn't stop the app during most of its run, you'd also need a bit more tenured space. Finally it fragments tenured and if a big object is promoted and there's no longer enough consecutive free space, then once a non-CMS GC will kick in (with the normal pause times), clean up and thus defragment everything as a side effect. So even with CMS you might occasionally see a non-CMS GC running. On a modern system, especially server type, the non-CMS GC runs on multiple threads in parallel. Since our default heap size is "only" 0.5 GB, the pause times caused by GC should be acceptable. So I'd stay with the non-CMS GC as the default setting. But if one needs multi-GB heap then switching to CMS could make sense in order to avoid multi-second pauses every now and then. I suggest to add a commented CMS block using -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSClassUnloadingEnabled -XX:+ExplicitGCInvokesConcurrent (the last of the four switches lets System.gc() but also the Distributed DGC triggered e.g. by RMI also run as CMS; without the switch those would run as non-CMS). Typically one would also like to tune: -XX:ParallelGCThreads=N (some N depending on hardware) -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=NN (some percentage NN depending on memory behavior) -XX:CMSInitiatingPermOccupancyFraction=MM (some percentage MM depending on memory behavior) but there's no general recommendation possible for values, so we should just ignore these. In addition I propose to set "DEBUG" to following switches for the GC log: -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime The only real downside here is that PrintGCDateStamps was only introduced in 1.6.0_04. But since DEBUG is not active by default and it is unlikely someone needing to debug stuff has Java 6 before update 04 running I suggest to add the flag. I don't know whether there will be a problem with a to long command line when actually using the flags on one of the supported platforms. Since Java 1.6.0_35 and 1.7.0_07 there's also a way to write the GC log to a rotating log file: -Xloggc:FILENAME -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M (example values). But that's to fresh to assume in general, and since JMeter is not a server daemon it should be OK to write the GC stuff to STDOUT by default. Otherwise we could simply add the single switch -Xloggc:gc.log which will always start a new gc log after JMeter start, overwriting the previous log. Regards, Rainer > If not then let's remove it, otherwise +1 for your proposition of commented > block for CMS. > > On Sat, Jul 27, 2013 at 8:17 PM, Rainer Jung <rainer.j...@kippdata.de>wrote: > >> On 26.07.2013 22:06, pmoua...@apache.org wrote: >>> Author: pmouawad >>> Date: Fri Jul 26 20:06:10 2013 >>> New Revision: 1507418 >>> >>> URL: http://svn.apache.org/r1507418 >>> Log: >>> Add a GC option for perm cleanup >>> Add explanation on NEW zone >>> >>> Modified: >>> jmeter/trunk/bin/jmeter >>> >>> Modified: jmeter/trunk/bin/jmeter >>> URL: >> http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter?rev=1507418&r1=1507417&r2=1507418&view=diff >>> >> ============================================================================== >>> --- jmeter/trunk/bin/jmeter (original) >>> +++ jmeter/trunk/bin/jmeter Fri Jul 26 20:06:10 2013 >>> @@ -45,7 +45,7 @@ HEAP="-Xms512m -Xmx512m" >>> >>> # There's an awful lot of per-sample objects allocated during test run, >> so we >>> # need a large eden to avoid too frequent scavenges -- you'll need to >> tune this >>> -# down proportionally if you reduce the HEAP values above: >>> +# down proportionally if you modify the HEAP values above: >>> NEW="-XX:NewSize=128m -XX:MaxNewSize=128m" >>> >>> # This ratio and target have been proven OK in tests with a specially >> high >>> @@ -75,7 +75,7 @@ TENURING="-XX:MaxTenuringThreshold=2" >>> RMIGC="-Dsun.rmi.dgc.client.gcInterval=600000 >> -Dsun.rmi.dgc.server.gcInterval=600000" >>> >>> # Increase MaxPermSize if you use a lot of Javascript in your Test Plan >> : >>> -PERM="-XX:PermSize=64m -XX:MaxPermSize=128m" >>> +PERM="-XX:PermSize=64m -XX:MaxPermSize=128m >> -XX:+CMSClassUnloadingEnabled" >> > Note that the switch wouldn't do anything by default, because it only is >> effective is the user switches to CMS garbage collection >> (-XX:+UseConcMarkSweepGC). If CMS is not used, class unloading is >> default (boolean switch ClassUnloading). Fortunately the >> CMSClassUnloadingEnabled switch is simply ignored if CMS is not used. >> >> OTOH it also has a side effect: it will let the CMS check how much >> memory in the perm gen is free to decide whether it should run. By >> default it will run when perm is 92% filled. This can be changed with >> the CMSInitiatingPermOccupancyFraction switch. It can not only run when >> the perm gen is full, like he traditional compactifying GC, because it >> is expected to run concurrently with the application, so there must be >> some free space left to let the app run successfully until the CMS has >> freed up garbage. >> >> So as long as JMeter stays typically below 92% that's fine, but if it >> frequently goes to 92%, e.g. because it always needs 91% and quickly >> adds temporary classes which make up the last percent, that would result >> in frequent CMS runs. This is something to keep in mind. >> >> Should we provide a commented block of switch prepared for the CMS use? >> >> Regards, >> >> Rainer