1. 程式人生 > >啟動jenkins時指定jvm引數

啟動jenkins時指定jvm引數

環境

java:1.7
jenkins:2.5
作業系統:win7
伺服器:centos6
工具:CRT

場景

今天jenkins用著用著報了以下錯誤(從日誌中檢視):

javax.servlet.ServletException: org.apache.commons.jelly.JellyTagException: jar:file:/home/jenkins/war/WEB-

INF/lib/jenkins-core-2.25.jar!/lib/layout/layout.jelly:83:72: <st:include> Error setting property 'page'
, exception - java.lang.OutOfMemoryError: PermGen space at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:103) at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746) at org.kohsuke.stapler.Stapler.invoke(Stapler.java:876) at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649
) at hudson.init.impl.InstallUncaughtExceptionHandler$1.reportException (InstallUncaughtExceptionHandler.java:30) at org.kohsuke.stapler.compression.CompressionFilter.reportException(CompressionFilter.java:77) at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:55
) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:553) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at org.eclipse.jetty.server.Server.handle(Server.java:499) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744) Caused by: org.apache.commons.jelly.JellyTagException: jar:file:/home/jenkins/war/WEB-INF/lib/jenkins-core- 2.25.jar!/lib/layout/layout.jelly:83:72: <st:include> Error setting property 'page', exception - java.lang.OutOfMemoryError: PermGen space at org.apache.commons.jelly.impl.TagScript.handleException(TagScript.java:726) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:281) at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161) at org.apache.commons.jelly.tags.core.ForEachTag.doTag(ForEachTag.java:150) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.tags.core.CoreTagLibrary$1.run(CoreTagLibrary.java:98) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.tags.core.CoreTagLibrary$1.run(CoreTagLibrary.java:98) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105) at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105) at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:95) at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:63) at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:53) at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:95) ... 29 more Caused by: java.lang.IllegalArgumentException: Error setting property 'page', exception - java.lang.OutOfMemoryError: PermGen space at org.apache.commons.beanutils.ConvertingWrapDynaBean.set(ConvertingWrapDynaBean.java:74) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:265) ... 44 more Caused by: java.lang.OutOfMemoryError: PermGen space 十一月 29, 2017 10:45:57 上午 org.eclipse.jetty.util.log.JavaUtilLog warn 警告: Could not send response error 500: javax.servlet.ServletException: org.apache.commons.jelly.JellyTagException: jar:file:/home/jenkins/war/WEB-INF/lib/jenkins-core- 2.25.jar!/lib/layout/layout.jelly:83:72: <st:include> Error setting property 'page', exception - java.lang.OutOfMemoryError: PermGen space

可以很明顯看出是記憶體溢位;

官網也給出瞭解決辦法:

修改jvm引數

我們先來看看官方是怎麼解釋(為什麼會記憶體溢位):

As your project grows, and you use new tools to either build or analyze your code, you will inevitably exceed the memory settings which your JVM provides by default. This is especially true on 64 bit JVM’s since they double the size of the reference pointer. This page aims to show you how to increase the memory available to your build process.

上面的意思是:

隨著我們專案的增長,和使用新的工具去構建或分析程式碼,會不可避免的超過jvm提供的預設值。這在64位jvm中尤為明顯,因為它們引用的指標大小是翻倍的(相對32位)。接下來將展示如何增加可用於構建過程的記憶體(通俗點說就是增加 jvm 可用的記憶體)。

Heap or Permgen

記憶體溢位分來兩種;

官方介紹:

There are two OutOfMemoryErrors which people usually encounter. The first is related to heap space: java.lang.OutOfMemoryError: Heap space When you see this, you need to increase the maximum heap space. You can do this by adding the following to your JVM arguments -Xmx200m where you replace the number 200 with the new heap size in megabytes.
The second is related to PermGen: java.lang.OutOfMemoryError: PermGen space. When you see this, you need to increase the maximum Permanent Generation space, which is used for things like class files and interned strings. You can do this by adding the following to your JVM arguments -XX:MaxPermSize=128m where you replace the number 128 with the new PermGen size in megabytes.

意思就是:

通常情況下,我們會遇到兩種記憶體溢位的錯誤。第一種是關於堆溢位:java.lang.OutOfMemoryError: Heap space;當你看到這個錯誤時,你需要增加堆空間的最大值。你可以新增以下內容作為jvm的引數:-Xmx200m,數字200你可以使用新值替換。比如4096即:-Xmx4096m
第二種是關於永久代的(java7以後版本會移除永久代):java.lang.OutOfMemoryError: PermGen space。當你看到這個錯誤時,你需要增加永久代空間的最大值,這個空間是被像 類檔案和interned字串所使用的。你可以新增以下內容作為jvm的引數:-XX:MaxPermSize=128m,數字128你可以使用新值替換。比如512即:-XX:MaxPermSize=512m

我的改法

很明顯我的問題是第二種,所以我需要使用-XX:MaxPermSize=128m這個引數:

我的改法是:

vim /etc/sysconfig/jenkins
# 找到 JENKINS_JAVA_OPTIONS
# JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"
# 改為
JENKINS_JAVA_OPTIONS="-XX:MaxPermSize=512m -Djava.awt.headless=true"

儲存好後,之後,在重啟jenkins。但是呢我啟動後,還是報記憶體溢位,連頁面都打不開。看了下程序:

[[email protected] log]# ps -ef | grep jenkins
root       357 45410  0 11:06 pts/4    00:00:00 grep jenkins
root     22293     1  0 Nov13 ?        00:54:21 /usr/java/jdk1.7.0_51/bin/java -cp /home/jenkins/dataspace/plugins/maven-plugin/WEB-INF/lib/maven32-agent-1.12-alpha-1.jar:/home/activemq/apache-maven-3.2.3/boot/plexus-classworlds-2.5.1.jar:/home/activemq/apache-maven-3.2.3/conf/logging jenkins.maven3.agent.Maven32Main /home/activemq/apache-maven-3.2.3 /var/cache/jenkins/war/WEB-INF/lib/remoting-2.62.jar /home/jenkins/dataspace/plugins/maven-plugin/WEB-INF/lib/maven32-interceptor-1.12-alpha-1.jar /home/jenkins/dataspace/plugins/maven-plugin/WEB-INF/lib/maven3-interceptor-commons-1.12-alpha-1.jar 48531
root     24012     1  0 Nov21 ?        01:38:52 /usr/java/jdk1.7.0_51/bin/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true -DJENKINS_HOME=/home/jenkins/dataspace -jar /home/jenkins/lib/jenkins.war --logfile=/home/jenkins/log/jenkins.log --webroot=/home/jenkins/war --daemon --httpPort=7080 --ajp13Port=-1 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20

這裡我們看到程序id:22293,這個程序估計是我之前啟動一個maven job依賴下來的,這個maven專案每次啟動都把jenkins直接跑崩了!殺死這個程序後,重啟jenkins就可以了

官方的改法

官方的改法都是在jenkins的配置頁面中進行修改,我之所沒這麼做,是因為我jenkins連頁面都打不開(因為記憶體溢位啦)。

maven型別專案

①全域性配置:
如果你使用的是Maven2/3專案型別,你可以在jenkins全域性配置中設定-Xmx or -XX:MaxPermSize。通過導航(Manage Jenkins -> Configure System),接著找到Maven Project Configuration,在Global MAVEN_OPTS這一欄中新增需要設定的jvm引數並點選儲存。隨後的Maven2/3 job構建將會使用新的設定。

②專案設定:
這個設定是針對每個job的。首先在job頁面中點選configure按鈕,接著找打Build部分並點選advanced,接著在MAVEN_OPTS這個選項中設定相關引數。

Freestyle projects with Maven Build Steps

如果你有一個自由式專案並使用Invoke Top Level Maven Targets構建步驟,你可以點選高階按鈕,在JVM Options這一欄新增jvm引數。

另外,可以在jenkins全域性配置,通過新增MAVEN_OPTS全域性變數來影響所有自由風格maven的構建步驟。具體配置路徑:先點選Manage Jenkins,接著Configure System,在Global properties這一欄中,勾選Environment Variables複選框,接著新增一個新的名為MAVEN_OPTS的環境變數,並設定一個合適的值:
這裡寫圖片描述

Gradle build steps

這裡同理上面,可以在系統設定中新增全域性變數

Ant build steps

對於Ant 步驟,其沒有全域性環境變數,你必須在每個單獨的構建步驟中設定Ant選項。在構建的設定中,找到Invoke Ant步驟,點選高階按鈕,Java Options這一欄輸入引數。