Tips on JVM tuning for Lucee

I thought it would be instructive if folks posted any JVM tuning tips that
help Lucee performance, stability, et al. I’ve tried some GC tuning
settings, but they don’t seem to work on the server. Guess I need to do
some more research.

Not having an issues, the server is just starting to be used for actual
applications. I will put off worrying about any JVM performance issues
until they actually arise. I was just curious to see whether there were
some good general purpose settings we could add before the server gets too

Thanks for all of the replies, it is all good information to have.

Always leave that till last.

Start on your DB, then your code and leave that kind of tuning till last. Check out this book for more tips:

Apart from increasing memory (if needed) I generally suggest that you fix as much in your app as possible before fiddling and copy and pasting settings from across the internet into your application.

Hi Jonathan,

Settings sample:


-Xmx: 4 GB (max. 32GB)
-Xms: as Xmx
-Xss: 256K

Garbage Collector:

The G1 Collector seems to need more CPU and RAM – but frees more memory.
If you don’t have more than 6 GB XmX you should select the CMS Collector.

Java Options for JDK 7 (with CMS GC = UseConcMarkSweepGC):

-javaagent:D:/ApacheTomcat-7.0.25/luceelib/lucee-inst.jar (nur Lucee)

Java Options for JDK 8 (with G1 GC = UseG1GC):

-javaagent:D:/ApacheTomcat-7.0.25/luceelib/lucee-inst.jar (nur Lucee)


1 Like

All you you are right to some extent :slight_smile:

There are lots of areas you can get easier performance gains from, mainly the database and your application.

Usually people only start looking into JVM tuning because there are issues - like long pauses or latency etc.

However that’s the wrong approach. Nearly all JVMs out there come pre-setup with non-suitable heap sizes and a high-throughput garbage collector. That might be fine if you run a small or a few small websites on a grunty server, but it will instantly produce really bad performance on large heap systems and system under high load.

The minimum what everyone who runs a web-based server on a JVM should do is:

a) set min and max memory suitable to hardware architecture (32/64 bit) and application(s) size(s) on the JVM.

b) If you have a heap larger than 2GB, change your Garbage Collector to Concurrent Mark Sweep, if you have a heap of even 6-8GB+ strongly consider G1 as an alternative to Concurrent Mark Sweep provided you’re on a late JVM 7 or a JVM 8. Both those collectors are low-pause collectors and Oracle themselves recommend them for server applications. Note: Both low-pause collectors will from experience create between 5-15% more CPU than the default collector — how much of an impact it will make depends on so many variables that it’s not worth elaborating on them on a mailing list, it’s just too much.

I would strongly advise against just blindly using what Harry has posted - not because those settings are bad, but because there are no settings that fit any random use case and using settings that are not suitable essentially can turn your performance to shit and make it even much worse than before.


1 Like

I agree with Mark. There are so many areas to concentrate on that will
yield performance benefits that tuning the memory usage should be left for

Also, since every application is different, there’s no silver bullet set of
parameters that will make the JVM run properly for every instance.

If you’re having stability issues, it’s in your application or database,
not in the JVM settings. I have Railo instances running thousands of
concurrent users with no issues. The only time we ever have to restart the
server or Railo is when there’s a network outage that borks up the entire


Some random guy did a good talk on this.


1 Like

Yup, I’m sure - just look in the table right below the one you quoted on the website you linked to :slight_smile:


Hi Kai,

Just a quick note, Harry - UseParNewGC is obsolete because UseConcMarkSweepGC automatically uses Parallel New for the YG in Java 7.

Thanks for your note, but are you sure about that?
See :

(Garbage Collectors Available In JDK 1.7.0_04)

The full list of possible GC algorithm combinations that can work are:
Command Options*

Resulting Collector Combination


young Copy and old MarkSweepCompact


young G1 Young and old G1 Mixed

-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy

young PS Scavenge old PS MarkSweep with adaptive sizing

-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:-UseAdaptiveSizePolicy

young PS Scavenge old PS MarkSweep, no adaptive sizing


young ParNew old MarkSweepCompact

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC

young ParNew old ConcurrentMarkSweep**

-XX:+UseConcMarkSweepGC -XX:-UseParNewGC

young Copy old ConcurrentMarkSweep**

*All the combinations listed here will fail to let the JVM start if you add another GC algorithm not listed, with the exception of -XX:+UseParNewGC which is only combinable with -XX:+UseConcMarkSweepGC

**there are many many options for use with -XX:+UseConcMarkSweepGC which change the algorithm, e.g.

  • -XX:+/-CMSIncrementalMode - uses or disables an incremental concurrent GC algorithm
  • -XX:+/-CMSConcurrentMTEnabled - uses or disables parallel (multiple threads) concurrent GC algorithm
  • -XX:+/-UseCMSCompactAtFullCollection - uses or disables a compaction when a full GC occurs



(Sah den Wald vor lauter Bäumen nicht)


Really - that’s what it’s come to? Discussing my marriage on a mailing list? :slight_smile:

Nope, just reminding him that even you are still human and have to answer
to “a higher power”. :wink:

Just so you know, Kai is always right. Always. :wink:


Good luck convincing Diane of that. :wink: