• Linux环境部署项目引起Out of Memory Error: PermGen Space的解决方案


    1. 背景

      前几天,在搭建项目时遇到到一些问题,现在整理记录一下。

      Linux环境:Red Hat Enterprise Linux Server release 6.4; 

    # 查看命令
    cat
    /etc/issue

      JDK版本:jdk1.7.0_80;

      Tomcat版本:apache-tomcat-7.0.79;

    2.经过

      由于之前曾使用Tomcat容器部署过项目,所以没有觉得有什么特别值得注意的地方,就是将web项目打成war包,放到Linux服务器tomcat容器下,然后启动Tomcat就OK了。

      然而,现实并不如想象的那么顺利。。。

      之前的部署是这么做的:Eclipse将web项目Export转成war,然后使用Xshell将该war包传至服务器(使用szrz命令,或其他传输工具),将war包放到Tomcat目录下的webapps下,然后回到tomcat目录下的bin目录,./start.sh,回车,整个工作就结束了。

      现在的IDE用的是idea,网上各种搜idea下怎么将web项目打成war,一看过程要设置好多事项,果断放弃,想着直接用Linux命令搞定:

    jar -cvf demo-web.war ./demo-web

      开始看需要部署的项目,从SVN上下载下来一看,喔,19个项目,之前都是一个war包搞定的呀,19个毫不犹豫看了下总共要2-3G,然后找了一个(WinSCP)工具开始上传,局域网按说应该好快的,可能是由于无线的原因吧,愣是传了2,3个小时。传上去之后,打war包,移到webapps目录下,启动tomcat,然后结果是这样的:

    严重: Error waiting for multi-thread deployment of directories to complete
    java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: PermGen space
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
        at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:1198)
        at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:530)
        at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1749)
        at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:370)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
        at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:388)
        at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:333)
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1136)
        at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:819)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1571)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1561)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        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:745)
    Caused by: java.lang.OutOfMemoryError: PermGen space
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:3205)
        at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:1373)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1861)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1735)
        at org.apache.catalina.util.Introspection.loadClass(Introspection.java:143)
        at org.apache.catalina.startup.ContextConfig.checkHandlesTypes(ContextConfig.java:2182)
        at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2120)
        at org.apache.catalina.startup.ContextConfig.processAnnotationsJar(ContextConfig.java:1981)
        at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:1942)
        at org.apache.catalina.startup.ContextConfig.processAnnotations(ContextConfig.java:1927)
        at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1332)
        at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:888)
        at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:388)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5522)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
        at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1296)
        at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:2038)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        ... 4 more

      一下愣住了,怎么会出现这个OutOfMemoryError,又重新试了几次,毫无例外,每次都是到这块报错OutOfMemoryError,看来只能是因为项目类太多,导致JVM内存被占满了,这个JVM的参数在哪里修改呢?百度了一下,基本可以确认需要更改的文件:tomcat/bin/catalina.sh,对就是tomcat的启动脚本文件,修改如下:

    # OS specific support.  $var _must_ be set to either true or false.
    JAVA_OPTS = "-Xms256m -Xmx512m -Xss128K -XX:PermSize=128m -XX:MaxPermSize=256m"

    这下,应该好了吧,再来一次,结果丝毫没有改变,是不是改错地方了,又在网上找了一会儿,试了试这个方案:修改jdk/jre/lib/security/java.security这个文件原来内容为:

    securerandom.source=file:/dev/urandom

    修改为:

    securerandom.source=file:/dev/./urandom

    重启来一次,还是不行。看看快一天了,不行呀,赶紧问下老大,还是这个catalina.sh这个参数设置的问题,然后又回来各种尝试,把”-Xms -Xmx -XX:PermSize -XX:MaxPermSize“各种调大,各种尝试,依然没有进展,好吧,这次先把18个项目删掉只留一个,一试,哦,这下可以了,好吧,继续增加项目个数2个,3个,。。。,8个,就8个了,8个项目就启动不了了,还是java.lang.OutOfMemoryError: PermGen space;这就奇怪了,看看服务器内存占用和CPU使用情况吧:

    [root@sv08 ~]# free
                 total       used       free     shared    buffers     cached
    Mem:       8061572    7893692     167880          0     454860    4351972
    -/+ buffers/cache:    3086860    4974712
    Swap:      8208376      21600    8186776
    [root@sv08 ~]# top
                

    这个看的还是有一定余量的,那只能是JVM参数的设置的问题了,继续网上找,试了几个修改catalina.properties和其他基本配置文件的方案,依然不起任何作用。

      这时候同事过来帮忙了,说是之前遇到过类似问题,然后开始对比,-Xms,-Xmx与系统硬件占用情况,依然是top命令和free命令,结论是有富余,然后这是各种调catalina.sh的参数,没有任何效果,然后又开始注释项目代码,这类问题也可能与代码有关的了,然而,多次尝试之后也没有好的效果。

      问题总得解决呀,眼下也没有什么好的办法,多尝试尝试吧,又继续尝试网上得方案, 各种试,终于,这样试了一下:

    # OS specific support.  $var _must_ be set to either true or false.
    JAVA_OPTS="-server -XX:PermSize=256m -XX:MaxPermSize=512m"

      这个方案一试之后,8个项目可以启动了,呃呃,毫不犹豫,19个项目一起上,结果又出现了这个java.lang.OutOfMemoryError: PermGen space,尝试这个把后面俩个参数调大一倍,最终设置:

    # OS specific support.  $var _must_ be set to either true or false.
    JAVA_OPTS="-server -XX:PermSize=512m -XX:MaxPermSize=1024m"

    ./start.sh,启动成功!

    参考链接:

    https://blog.csdn.net/kongls08/article/details/8468713

    3.总结

      这个没有太多要说的,还是要多掌握下JVM的调优,明白各个参数的意义,以及调优的原理,大家有好的资源可以分享出来一起学习;然后就是多实践了,光有想法是远远不够的,多实践才能总结出更多有用的东西,分享给大家。

      

  • 相关阅读:
    超链接标签的CSS伪类link,visited,hover,active
    CSS系列(8) CSS后代选择器和子选择器详解
    CSS系列(7)CSS类选择器Class详解
    CSS系列(6) CSS通配符详解
    CSS系列(5)-如何使用Firebug查看网页的html和css
    我给女朋友讲编程CSS系列(4) CSS盒子模型
    两次理发感悟到的人生
    我给女朋友讲编程CSS系列(3) CSS如何设置字体的类型、大小、颜色,如何使用火狐浏览器的Firebug插件查看网页的字体
    SSH不允许进行DNS解析
    项目发布平台
  • 原文地址:https://www.cnblogs.com/yuhuashang-edward/p/9995195.html
Copyright © 2020-2023  润新知