美文网首页
tomcat关闭报错:error='Cannot allocat

tomcat关闭报错:error='Cannot allocat

作者: hellohuan | 来源:发表于2018-05-24 18:03 被阅读0次

    最近在使用 tomcat 的时候,总是在shutdown出现error='Cannot allocate memory' (errno=12)错误。起初只当是偶然因素引起的,所以没有重视。可是后来发现每次都会出现这个错误,所以这次决心找到原因解决。

    第一步

    首先观察报错信息如下:

    Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000eaaa0000, 357957632, 0) failed; error='Cannot allocate memory' (errno=12)
    #
    # There is insufficient memory for the Java Runtime Environment to continue.
    # Native memory allocation (mmap) failed to map 357957632 bytes for committing reserved memory.
    # An error report file with more information is saved as:
    # /home/gaea/tomcat-api/hs_err_pid14638.log
    

    看#里面的内容,主要表达:Java 运行所需内存不足,本地内存分配为提交保留的内存分配失败。看到这里,突然想到之前在 catalinn.sh 中更改过虚拟机的启动参数,如下:

    JAVA_OPTS="-Xms512m -Xmx1024m -Xss1024K"
    

    第二步

    分析错误信息:

    • 众所周知,-Xms 表示堆的大小,-Xmx 表示堆的最大值。当 Java 虚拟机的堆内存不够时,就会向操作系统请求保留的堆内存,即堆的最大值与当前堆大小的差值。这样设置的目的是为了让虚拟机有更好性能收缩弹性,但是在这里适得其反了,因为当前 tomcat 运行的主机内存为 2GB。除了tomcat 之外,系统中还运行着其他服务,这就导致在 Java 虚拟机向操作系统请求分配保留的堆内存时,系统无法分配。
    • 这里就引出了第二个问题,为什么只是shutdown的时候才出现报错,而 tomcat 没有宕掉。这是因为在shutdown时,需要单独一个进程来运行关闭tomcat时的一些操作,所以需要更多的内存,恰恰这些需要分配的内存超过了本地内存的上限,导致分配失败。所谓『压死骆驼的最后一根稻草』。

    第三步

    既然知道了问题的原因,解决起来就比较方便了,直接在 catalina.sh 中将虚拟机启动参数修改如下:

    JAVA_OPTS="-Xms512m -Xmx512m -Xss1024K"
    

    这样就解决问题了。

    思考

    通过上诉问题的解决,可以得出结论:

    • 不要在内存吃紧的情况下,采用 -Xmx的方式动态分配堆内存。

    版权声明:本文为博主原创文章,未经博主允许不得转载。
    https://www.jianshu.com/p/08ca8dc4b5f0

    相关文章

      网友评论

          本文标题:tomcat关闭报错:error='Cannot allocat

          本文链接:https://www.haomeiwen.com/subject/cqwsjftx.html