• 异常


    1 环境配置信息

    1.1 服务器配置信息

    服务器是物理机, 配置信息如下:

    CPU型号 CPU个数 CPU核数 CPU线程数 内存
    Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz 2个 2 * 10 = 20个核 2 * 20 = 40个线程 126G

    1.2 Tomcat启动参数

    查看$TOMCAT_HOME/bin/catalina.sh文件, 其中JVM参数配置信息如下:

    JAVA_OPTS="-server -Xms90g -Xmx90g -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC"
    

    2 问题描述

    在服务器(CentOS-6.5)中部署项目上线前的仿真测试环境, 启动Tomcat时, 抛出如下错误:

    Error occurred during initialization of VM
    Could not reserve enough space for object heap
    Error: Could not create the Java Virtual Machine.
    Error: A fatal exception has occurred. Program will exit.
    

    也就是: 初始化VM时出错, 无法为heap(堆)对象保留足够的空间.

    错误: 无法创建Java虚拟机.

    错误: 发生了致命异常. 程序将会退出.

    3 问题解决

    根据问题描述可知, Linux系统不允许初始化JVM时就申请这么大的内存.

    (1) JVM可用内存测试方法:

    # 配置好JDK的环境变量后, 在终端键入如下命令: 
    java -Xmx32g -version
    
    # 如果能够正常显示JDK的版本信息, 说明可以申请到指定大小的内存. 
    # 若报错, 说明申请的内存大小超出限制, 不被操作系统所允许. 
    

    (2) 继续查看系统资源限制情况:

    # 在终端键入如下命令: 
    ulimit -a
    # 发现内存的使用并未受限: 
    max locked memory       (kbytes, -l) 64
    max memory size         (kbytes, -m) unlimited
    

    经过排查, 原来某同事在测试Greenplum DB时, 修改了/etc/sysctl.conf文件中的系统内核参数.

    # 将如下参数的值设置为1或0
    vm.overcommit_memory=2
    
    # 保存退出后, 使得更改生效: 
    sysctl -p
    

    此时再次启动Tomcat, 发现启动成功.

    4 关于vm.overcommit_memory参数

    vm.overcommit_memory表示系统内核在分配内存时做检查的方式.

    此参数有 [0、1、2] 3个值可选, 处理方式定义在内核源码mm/mmap.c_vm_enough_memory函数中.

    4.1 vm.overcommit_memory=0

    默认设置. 宏为OVERCOMMIT_GUESS.

    内核计算: NR_FILE_PAGES总量 + SWAP总量 + slab中可以释放的内存总量, 如果申请空间超过此数值, 则将此数值与空闲内存总量减掉 totalreserve_pages() 的总量相加. 如果申请空间依然超过此数值, 则分配失败.

    该设置可能造成内存超载, 但也可以提升大量使用内存的任务的性能.

    4.2 vm.overcommit_memory=1

    宏为OVERCOMMIT_ALWAYS.

    函数直接 return 0, 分配成功.

    4.3 vm.overcommit_memory=2

    宏为OVERCOMMIT_NEVER.

    内核计算: 总物理内存 * vm.overcommit_ratio / 100 +SWAP总量, 如果申请空间超过此数值, 则分配失败. vm.overcommit_ratio 默认值为50.

    该设置可以有效减少内存过度使用的风险.

    4.4 查看系统的可用内存

    查看命令如下:

    [root@localhost ~]# grep -i commit /proc/meminfo
    CommitLimit:    66020980 kB
    Committed_AS:   100135888 kB
    

    其中:

    CommitLimit: 当前系统还可以申请的总内存;

    Committed_AS: 当前系统中所有应用申请了的总内存 —— 只是申请, 并未完全分配.

    参考资料

    linux 内存分配限制,overcommit_memory 2

    sysctl 中 vm.overcommit_memory 的含义

    版权声明

    作者: 马瘦风

    出处: 博客园 马瘦风的博客

    您的支持是对博主的极大鼓励, 感谢您的阅读.

    本文版权归博主所有, 欢迎转载, 但请保留此段声明, 并在文章页面明显位置给出原文链接, 否则博主保留追究相关人员法律责任的权利.

  • 相关阅读:
    校验相关问题
    类型转换和操作符重载 (c#)
    泛型委托Func<string,string>()
    第三次作业 刘惠惠
    刘惠惠1.12
    第二次作业刘惠惠2.6,2.15
    刘惠惠1.8
    第四次作业 刘惠惠
    刘惠惠1.2
    设计模式中的单件模式
  • 原文地址:https://www.cnblogs.com/shoufeng/p/10562794.html
Copyright © 2020-2023  润新知