Tuning My IntelliJ IDE

Jeremy Song
Stochastic Stories
Published in
2 min readAug 16, 2017

Introduction

I have been using IntelliJ IDE for Java development (occasionally Javascript development) for more than 3 years now. It’s probably the biggest application (in terms of the amount of resources it consumes) running on my working laptop. Even though at most time it’s running very smoothly, I wonder if I could make it run even faster by tuning the JVM options.

Default IntelliJ JVM Options

The following configuration is the default JVM configuration for IntelliJ 2017.2.

-Xms128m
-Xmx750m
-XX:ReservedCodeCacheSize=240m
-XX:+UseCompressedOops
-Dfile.encoding=UTF-8
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Xverify:none

-XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log
-XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof
-Xbootclasspath/a:../lib/boot.jar

The Good

  • It does not specify the specific compiler for the Java application. What’s good about this is that Java 8 uses tiered compilation. Tiered compilation was introduced in Java 7 with the idea that your Java bytecode is first compiled with client compiler and later on switched to servercompiler. Tiered compilation now is turned on by default in Java 8. For a GUI application like Intellij, this could make sure that your application runs with compiled code most of time.
  • It automatically does a heap dump when OOM occurs.

The Bad

  • Initial heap size is too low. 128M is too small for a writing a complex web application. If the JVM uses more than 128M heap size anyway, we should bump this value.
  • Maximum heap size is too low. 750M is also too small for large Java applications. My laptop has 16GB memory and I would give Intellij more memory.

Custom JVM Options

Here is my custom JVM configuration. You can learn how to change JVM options for IntelliJ here.

# custom IntelliJ IDEA VM options

-Xms1G
-XX:ReservedCodeCacheSize=480m
-XX:+UseCompressedOops
-Dfile.encoding=UTF-8
-XX:+UseG1GC
-XX:MaxGCPauseMillis=100
-XX:+PerfDisableSharedMem
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Xverify:none

-XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log
-XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof
-Xbootclasspath/a:../lib/boot.jar

Changes

  1. I changed initial heap size (-Xms) to 1G. I used jconsole to connect to my IntelliJ JVM process and observed that it frequently uses about 900MB memory. So I bumped this value to 1GB.
  2. I removed maximum heap size (-Xmx). By default, JVM calculates this value ergonomically by setting it to 1/4 of your physical memory. Since my laptop runs with 16GB memory, 4GB is a decent number.
  3. I switched the GC algorithm from CMS to G1. Both algorithms are concurrent GCs. But CMS uses mark-and-sweep, which suffers from memory fragmentation issue. It will perform a full GC to compact the memory. But during the full GC, it will stop the application, which will definitely affect the GUI user experience. G1GC is less likely to do a full GC.
  4. I set MaxGCPauseMillis to 100ms. It will basically set a goal for the GC so JVM can decide how much heap size to use.
  5. I bumped the code cache size to 480MB. This decides how much compiled code the JVM can have. Once the code cache is full, JVM will stop compiling bytecode. If the size is too small, it will definitely hurt the Java application performance. But I didn’t gather data to prove that my IntelliJ application need more than 240M code cache. So I am exercising a black magic here.
  6. I turned on PerfDisableSharedMem.

--

--

Jeremy Song
Stochastic Stories

I am currently a Principal Software Development Engineer at Amazon. All opinions are my own.