zoukankan      html  css  js  c++  java
  • -bash: fork: Cannot allocate memory

    今天遇到服务器无法SSH,VNC操作命令提示fork:cannot allocate memory

    free查看内存还有(注意,命令可能要多敲几次才会出来)


    查看最大进程数 sysctl kernel.pid_max



    ps -eLf | wc -l查看进程数
     

    确认是进程数满了

    修改最大进程数后系统恢复
    echo 1000000 > /proc/sys/kernel/pid_max

    永久生效
    echo "kernel.pid_max=1000000 " >> /etc/sysctl.conf
    sysctl -p

    (二)

    [root@elcid-prod1 ~]# java -version

    Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00007ff55c5ea000, 4096, 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 4096 bytes for committing reserved memory.

    # An error report file with more information is saved as:

    # /root/hs_err_pid5138.log

      

    查找了一下相关文档,发现这个错误的含义其实就是像它自己说的,没法分配内存了。

    The problem is inherent with the way Java allocates memory when executing processes. When Java executes a process, it must fork() then exec(). Forking creates a child process by duplicating the current process. By duplicating the current process, the new child process will request approximately the same amount of memory as its parent process, essentially doubling the memory required. However, this does not mean all the memory allocated will be used, as exec() is immediately called to execute the different code within the child process, freeing up this memory. As an example, when Stash tries to locate git, the Stash JVM process must be forked, approximately doubling the memory required by Stash.

    解决方案呢有两个,第一个是用别的方法(例如 posix_spawn)替换掉 Java 的 fork/exec 方法从而申请到内存,第二个是开启系统的 Over-commit,跳过系统的可用内存检查直接分配。

    第一个方法比较麻烦,需要使用一个 custom JNI binding 去更改 Java 底层调用,所以先不尝试。

    第二个方法比较简单,但可能会导致依赖 C 语言 malloc() 的程序出错。

    总之先试试第二个吧,毕竟就是改下系统变量的事儿。

    临时更改: echo 1 > /proc/sys/vm/overcommit_memory

    永久更改: 编辑 /etc/sysctl.conf,修改参数 vm.overcommit_memory = 1,重启服务器或者用户重新登录

    (三)swappiness设置

    swappiness的值的大小对如何使用swap分区是有着很大的联系的。swappiness=0的时候表示最大限度使用物理内存,然后才是 swap空间,swappiness=100的时候表示积极的使用swap分区,并且把内存上的数据及时的搬运到swap空间里面。linux的基本默认设置为60,具体如下:


    一般默认值都是60   

    [root@timeserver ~]# cat /proc/sys/vm/swappiness
    60

    也就是说,你的内存在使用到100-60=40%的时候,就开始出现有交换分区的使用。大家知道,内存的速度会比磁盘快很多,这样子会加大系统io,同时造的成大量页的换进换出,严重影响系统的性能,所以我们在操作系统层面,要尽可能使用内存,对该参数进行调整。

    临时调整的方法如下,我们调成10:
    [root@timeserver ~]# sysctl vm.swappiness=10
    vm.swappiness = 10
    [root@timeserver ~]# cat /proc/sys/vm/swappiness
    10
    这只是临时调整的方法,重启后会回到默认设置的

    要想永久调整的话,需要将
    需要在/etc/sysctl.conf修改,加上:
    [root@timeserver ~]# cat /etc/sysctl.conf

    # Controls the maximum number of shared memory segments, in pages
    kernel.shmall = 4294967296
    vm.swappiness=10


    激活设置

    [root@timeserver ~]# sysctl -p

    在linux中,可以通过修改swappiness内核参数,降低系统对swap的使用,从而提高系统的性能。


    遇到的问题是这样的,新版本产品发布后,每小时对内存的使用会有一个尖峰。虽然这个峰值还远没有到达服务器的物理内存,但确发现内存使用达到峰值时系统开始使用swap。在swap的过程中系统性能会有所下降,表现为较大的服务延迟。对这种情况,可以通过调节swappiness内核参数降低系统对swap的使用,从而避免不必要的swap对性能造成的影响。


    简单地说这个参数定义了系统对swap的使用倾向,默认值为60,值越大表示越倾向于使用swap。可以设为0,这样做并不会禁止对swap的使用,只是最大限度地降低了使用swap的可能性。


    通过sysctl -q vm.swappiness可以查看参数的当前设置。


    修改参数的方法是修改/etc/sysctl.conf文件,加入vm.swappiness=xxx,并重起系统。这个操作相当于是修改虚拟系统中的/proc/sys/vm/swappiness文件,将值改为XXX数值。


    如果不想重起,可以通过sysctl -p动态加载/etc/sysctl.conf文件,但建议这样做之前先清空swap。

  • 相关阅读:
    账户余额查询SQL(分类帐)
    基本值集定义
    EBS 各模块数据传送至总帐 需要运行的请求
    OU、库存组织与子库存
    AP 付款凭证
    WIP 完工入库单
    R12客户表结构分析
    ORACEL R12 总账和子账的关系
    JavaScript(转)
    ftp服务自动上传6410版子上的开发环境的设置
  • 原文地址:https://www.cnblogs.com/zhengchunyuan/p/10109626.html
Copyright © 2011-2022 走看看