The Jenkins controller’s Java Virtual Machine (JVM) ran out of heap memory, preventing it from allocating further objects and causing the build process to halt.

Common Causes and Fixes

1. Insufficient Heap Size for Jenkins Controller JVM

  • Diagnosis: Check the Jenkins controller’s startup script (usually jenkins.sh or jenkins.bat in the JENKINS_HOME/init.groovy.d or script directory) for -Xmx and -Xms JVM arguments. You can also check the process itself using ps aux | grep jenkins and then jcmd <pid> VM.flags.
  • Fix: Increase the -Xmx (maximum heap size) value. For example, if it’s set to -Xmx2g, change it to -Xmx4g. This gives the JVM more memory to work with.
    # Example modification in jenkins.sh
    JAVA_OPTS="-Djava.awt.headless=true -Xmx4g -XX:MaxPermSize=512m"
    
  • Why it works: The -Xmx flag directly controls the maximum amount of memory the JVM can allocate for its heap, where objects are stored. Increasing this limit allows Jenkins to manage larger datasets and more concurrent operations without exhausting memory.

2. Memory Leaks in Jenkins Plugins

  • Diagnosis: Monitor the Jenkins controller’s memory usage over time using tools like jvisualvm, jmc, or by periodically checking jcmd <pid> GC.heap_info. If memory steadily increases and never drops significantly after garbage collection, a leak is probable. Look for plugins that have been recently updated or are known to be resource-intensive.
  • Fix: Identify and disable or update the suspect plugin. If a specific plugin is found to be leaking memory (e.g., a custom plugin or one with a known bug), disable it temporarily or upgrade to a newer version that has fixed the leak.
    # Example: Disabling a plugin via Jenkins UI (Manage Jenkins -> Plugins -> Advanced)
    # Or by removing the plugin's .jpi file from JENKINS_HOME/plugins and restarting Jenkins.
    
  • Why it works: Plugins run within the Jenkins controller’s JVM. A poorly written plugin can continuously create objects that are never garbage collected, gradually consuming all available heap space. Removing or fixing the faulty plugin stops this continuous allocation.

3. Excessive Build History or Log Storage

  • Diagnosis: Check JENKINS_HOME/builds and JENKINS_HOME/logs. If these directories are extremely large or contain millions of entries, Jenkins might be struggling to manage this data in memory.
  • Fix: Configure Jenkins to limit build history. Go to Manage Jenkins -> Configure System -> Keep this number of builds for each job and set a reasonable limit (e.g., 5-10). Also, consider using the "Log Rotation" plugin to prune old logs.
    # Example: Setting build history limit in Jenkins UI
    # Navigate to Manage Jenkins -> Configure System
    # Under "Builds", set "Keep this number of builds for each job" to 10.
    
  • Why it works: Jenkins keeps metadata and sometimes parts of build logs in memory. An enormous build history means a vast amount of data that the JVM needs to manage, potentially leading to memory pressure. Limiting history reduces this overhead.

4. Large Workspace or Artifacts Stored on Controller

  • Diagnosis: Examine the Jenkins controller’s disk usage, particularly within JENKINS_HOME/workspace. If individual job workspaces or the total workspace size is in the gigabytes, and these are not being cleaned up properly, it can indirectly affect memory.
  • Fix: Implement workspace cleanup strategies. Use the "Delete workspace before build starts" option in job configurations or the "Workspace Cleanup" plugin. Also, ensure large artifacts are not being unnecessarily stored on the controller by the build jobs.
    # Example: Enabling workspace cleanup in a job configuration (Jenkins UI)
    # Navigate to job configuration -> Build Environment
    # Check "Delete workspace before build starts".
    
  • Why it works: While workspace files are on disk, Jenkins might load certain metadata or file listings into memory during operations, especially if there are many files. Aggressive cleanup reduces the amount of data Jenkins needs to index or process in memory.

5. High Concurrency or Too Many Agents Connected

  • Diagnosis: Monitor the number of concurrent builds and connected agents via the Jenkins UI (Manage Jenkins -> Nodes). If the number of running builds or connected agents is consistently very high, it strains the controller’s resources.
  • Fix: Distribute the load by adding more Jenkins agents or scaling up existing ones. Reduce the number of concurrent builds allowed per job or globally if possible.
    # Example: Limiting concurrent builds in a job configuration
    # Navigate to job configuration -> General
    # Under "Throttle Concurrent Builds", configure a strategy.
    
  • Why it works: Each running build and connected agent requires the controller to maintain state, manage communication, and dispatch tasks. High concurrency means more state and more communication overhead, consuming memory.

6. Outdated Jenkins Core or Java Version

  • Diagnosis: Check the Jenkins version (Manage Jenkins -> About Jenkins) and the Java version used by the controller (java -version in the controller’s environment).
  • Fix: Upgrade Jenkins to the latest stable version and ensure you are using a supported and recent Java LTS version (e.g., Java 11 or 17).
    # Example: Checking Jenkins version in UI
    # Manage Jenkins -> About Jenkins
    # Example: Checking Java version on controller
    # ssh <controller_ip> java -version
    
  • Why it works: Newer versions of Jenkins and Java often include performance improvements and memory management optimizations that can mitigate previous issues. Older versions might have known memory leaks or less efficient garbage collection.

7. Large jenkins.model.Jenkins.instance.extensionList

  • Diagnosis: This is a more advanced leak. If you suspect this, you can take a heap dump and analyze it with tools like Eclipse MAT or VisualVM. Look for a large number of ExtensionFinder or similar objects referencing many Extension implementations.
  • Fix: This is often caused by plugins that register many extensions dynamically without proper unregistration or by plugins that are no longer active but their extensions remain loaded. Identifying the specific plugin(s) is key. Removing or fixing those plugins is the solution.
  • Why it works: Jenkins uses an extension mechanism to discover and load various functionalities. If this list grows unbounded due to faulty plugin behavior, it consumes significant heap space.

After fixing the OutOfMemoryError, you might encounter a java.lang.OutOfMemoryError: PermGen space or java.lang.OutOfMemoryError: Metaspace if your -XX:MaxPermSize (for older Java versions) or Metaspace settings are too low, as the JVM needs space for class metadata.

Want structured learning?

Take the full Jenkins course →