almost 7 years ago

這個問題不只是針對OpenDayLight,如果當你執行java程式時出現了java.lang.OutOfMemoryError: PermGen space的錯誤訊息,都可以使用下列方法解決問題

PermGen space全名為Permanent Generation space,jvm在執行程式時會有一區塊的記憶體是永久保留直到程式結束,這部份常用來放置一些meta訊息。
而java defult permgen value如果不夠的話就會造成此問題(OutOfMemoryError: PermGen space)。

  • 此時其實只需要在執行java程式時指定PermGen大小即可,而此大小通常有兩種變數如下
    -XX:PermSize=512m     //預設給定的記憶體保留大小
    -XX:MaxPermSize=1024m //最大給定的記憶體大小
    

此雖然網路上很多解法都是直接設定環境變數就可以運行成功,例如

export JAVA_OPTS="-XX:PermSize=512m -XX:MaxPermSize=1g"
export JAVA_PERM_MEM="512m"
export JAVA_MAX_PERM_MEM="1024m"

但經過我的測試,這樣是不一定有效的,因為我們在執行程式的時候經常是透過別人撰寫好的script,如果這些script沒有將這些環境變數執行的納入考量那就沒有用了。

  • 故可以直接在執行java的command上加入設定,如 "java XXX.jar -XX:PermSize=512m -XX:MaxPermSize=1024m"
  • (我的java底子很差...可能理解或敘述不夠精確,如果有更正確的想法我會再更改的)

進入解決opendaylight執行error正題

根據以上的想法,我們可以在opendaylight的run script上進行修改(run.sh or run.internal.sh)

  • 打開run.internal.sh
  • 移到最後面,會看到類似下面的程式碼
    $JAVA_HOME/bin/java ${extraJVMOpts} \
    
    ${agentPath} \
    
    -Djava.io.tmpdir="${iotmpdir}/work/tmp" \
    
    -Dosgi.install.area="${bdir}" \
    
    -Dosgi.configuration.area="${confarea}/configuration" \
    
    -Dosgi.frameworkClassPath="${fwclasspath}" \
    
    .....(省略)
    elif [ "${consolestart}" -eq 1 ]; then
    .... (省略) 
    $JAVA_HOME/bin/java ${extraJVMOpts} \
    
    ${agentPath} \
    
    -Djava.io.tmpdir="${iotmpdir}/work/tmp" \
    
    -Dosgi.install.area="${bdir}" \
    
    ....(省略)
    這部分的兩個判斷是內都是用來執行opendaylight的程式碼 而上面是執行後會開啟遠端console port,而下面的部分不會 所以需要在執行的參數上加上Pergen記憶體大小設定 修改後如下
    $JAVA_HOME/bin/java ${extraJVMOpts} \
    
    -XX:PermSize=512m -XX:MaxPermSize=1024m \
    
    ${agentPath} \
    
    -Djava.io.tmpdir="${iotmpdir}/work/tmp" \
    
    -Dosgi.install.area="${bdir}" \
    
    -Dosgi.configuration.area="${confarea}/configuration" \
    
    -Dosgi.frameworkClassPath="${fwclasspath}" \
    
    .....(省略)
    elif [ "${consolestart}" -eq 1 ]; then
    .... (省略) 
    $JAVA_HOME/bin/java ${extraJVMOpts} \
    
    -XX:PermSize=512m -XX:MaxPermSize=1024m \
    
    ${agentPath} \
    
    -Djava.io.tmpdir="${iotmpdir}/work/tmp" \
    
    -Dosgi.install.area="${bdir}" \
    
    ....(省略)
    如此即可避免java.lang.OutOfMemoryError: PermGen space的錯誤訊息
  • 如果是要設定整體的java執行記憶體大小可以設定script裡的jvmMaxMemory參數,例如jvmMaxMemory="-Xmx3G"

如果您是在run opendaylight helium版的./karaf 時發生錯誤的訊息,可以由下方法解決

  • 設定下列環境變數即可
    export JAVA_PERM_MEM="512m"
    export JAVA_MAX_PERM_MEM="1024m"
    
← update ovs to 2.3.0 in mininet Build OpenDaylight helium-SR3 on Ubuntu 14.04 →