Linux 系统 vm.overcommit_memory 内核参数

目录

场景:    

分析问题: 

         1,对比法     

         2,看内核说明文档   

         3,下面的文档已经说的很清楚了。      

         4,如何计算虚拟内存?   

         5,下面来测试这两个参数:  

结论:    

相关概念

         1,内存映射

         2,虚拟内存

         3,随机访问存储器(ram)的使用

 

正文:

场景:
Server-A,Server-B机器的软硬件配置一样。4G内存、redhat5.3 64位虚拟机。

在Server-A上启动java程序ok,没问题

在Server-B上报如下错误:

#java  -Xmx10000m -version

Error occurred during initialization of VM

本篇文章来源于 站长资讯网 原文链接:http://www.net527.com/caozuoxitong/Linux/4074.html

分析问题:
1,对比法
首先用strace命令跟踪了下,内容太多,不好分辨,粗略地没看出啥结果。

两台相同配置的机器怎么一个可以,一个不行呢?比较一下内核参数吧!!

Server-A

#sysctl -a

vm.overcommit_memory = 0

Server-B

vm.overcommit_memory = 2

惊奇地发现了以上两个参数不同!但这两个参数代表什么意思?有什么作用?好,我们来看

2,看内核说明文档
建议大家用git命令克隆一份内核源码,这样方便搜索

#git clone "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git"

 

#grep "overcommit_memory" --color * -r

arch/unicore32/mm/init.c:               sysctl_overcommit_memory = OVERCOMMIT_ALWAYS;

arch/unicore32/mm/mm.h:extern int sysctl_overcommit_memory;

arch/arm/mm/init.c:             extern int sysctl_overcommit_memory;

arch/arm/mm/init.c:             sysctl_overcommit_memory = OVERCOMMIT_ALWAYS;

Documentation/sysctl/vm.txt:- overcommit_memory

Documentation/sysctl/vm.txt:overcommit_memory:

Documentation/sysctl/vm.txt:When overcommit_memory is set to 2, the committed address

Documentation/vm/overcommit-accounting:The overcommit policy is set via the sysctl `vm.overcommit_memory'.

Documentation/filesystems/proc.txt:              'vm.overcommit_memory').

省略部分文字...

mm/mmap.c: * vm.overcommit_memory sysctl.  See Documentation/vm/overcommit-accounting

mm/mmap.c:      if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS)

mm/mmap.c:      if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {

mm/mmap.c:              if (sysctl_overcommit_memory != OVERCOMMIT_NEVER)

3,下面的文档已经说的很清楚了。
关键点:

1,总共有三个参数,缺省值为0

2,这个值的设定还和overcommit_ratio参数有关

3,欲了解更多详情,请看overcommit-accounting

 

#vi Documentation/sysctl/vm.txt

省略部分文字...

==============================================================

 

overcommit_memory:

 

This value contains a flag that enables memory overcommitment.

 

When this flag is 0, the kernel attempts to estimate the amount

of free memory left when userspace requests more memory.

 

When this flag is 1, the kernel pretends there is always enough

memory until it actually runs out.

 

When this flag is 2, the kernel uses a "never overcommit"

policy that attempts to prevent any overcommit of memory.

 

This feature can be very useful because there are a lot of

programs that malloc() huge amounts of memory "just-in-case"

and don't use much of it.

 

The default value is 0.

 

See Documentation/vm/overcommit-accounting and

security/commoncap.c::cap_vm_enough_memory() for more information.

==============================================================

overcommit_ratio:

When overcommit_memory is set to 2, the committed address

space is not permitted to exceed swap plus this percentage

of physical RAM.  See above.

 

# vi Documentation/vm/overcommit-accounting

The Linux kernel supports the following overcommit handling modes

 

0   -   Heuristic overcommit handling. Obvious overcommits of

        address space are refused. Used for a typical system. It

        ensures a seriously wild allocation fails while allowing

        overcommit to reduce swap usage.  root is allowed to

        allocate slightly more memory in this mode. This is the

        default.

 

1   -   Always overcommit. Appropriate for some scientific

        applications.

 

2   -   Don't overcommit. The total address space commit

        for the system is not permitted to exceed swap + a

 

configurable percentage (default is 50) of physical RAM.

        Depending on the percentage you use, in most situations

        this means a process will not be killed while accessing

        pages but will receive errors on memory allocation as

        appropriate.

省略后面文字...

 

4,如何计算虚拟内存?
总虚拟内存= 可用物理内存×百分比+ 交换分区

 

#cat /proc/meminfo |grep -i commit

CommitLimit:   4114264 kB           //最大可用虚拟内存

Committed_AS:  3821756 kB         //已使用虚拟内存

 

5,下面来测试这两个参数:
当前该内核参数值为2

#sysctl -n vm.overcommit_memory

2

执行命令报错

#java  -Xmx10000m -version

Error occurred during initialization of VM

Could not reserve enough space for object heap

Could not create the Java virtual machine.

 

修改该内核参数值为0

#sysctl -w vm.overcommit_memory=0

vm.overcommit_memory = 0

执行命令成功

#java  -Xmx10000m -version

java version "1.6.0_25"

Java(TM) SE Runtime Environment (build 1.6.0_25-b06)

Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)

 

结论:
永久性修改内核参数

在/etc/sysctl.conf文件里面加入或者直接删除也可以,因为它缺省值就是0

vm.overcommit_memory = 0

运行使之生效

#sysctl -p

 

补充:

为什么要调整overcommit_memory参数的值?因为之前安装过greenplum数据库。

 

相关概念
·与创建、删除线性区相关的系统调用

·fork()   创建一个新进程,并为它创建新的地址空间

 

1,内存映射
         内 存映射是一种重要的抽象手段。在内核中大量使用,也可以用于用户应用程序。映射方法可以将任意来源的数据传输到进程的虚拟地址空间中。作为映射目标的地址 空间区域,可以像普通内存那样用通常的方法访问。但任何修改都会自动传输到原数据源。这样就可以使用相同的函数来处理完全不同的目标对象。例如,文件的内 容可以映射到内存中。处理只需读取相应的内存即可访问文件内容,或向内存写入数据来修改文件的内容。内核将保证任何修改都会自动同步到文件中。

         内核在实现设备驱动程序时直接使用了内存映射。外设的输入/输出可以映射到虚拟地址空间的区域中。对相关内存区域的读写会由系统重定向到设备,因而大大简化了驱动程序的实现。

 

问:什么是内存映射?memory mapping

答:是内核的一种抽象手段,它可以将任意来源的数据映射到进程的虚拟地址空间。cpu处理任务时可以像处理普通内存中的数据结构一样,处理完后内核会自动将结果保存回数据源。


         图中所示两个进程的虚拟地址空间,都被内核划分为很多等长的部分。这些部分称之为页。物理内存也划分为同样大小的页。

         这种情况是可能的,因为两个虚拟地址空间中的页(虽然在不同的位置)可以映射到同一物理内存页。由于内核负责将虚拟地址空间映射到物理地址空间,因此可以决定哪些内存区域在进程之间共享,哪些不共享。

         并非虚拟地址空间的所有页都映射到某个页帧。这可能是因为页没有使用,或者是数据尚不需要使用而没有载入内存中。还可能是页已经换出到硬盘,将在需要时再换回内存。

2,虚拟内存
摘自《深入理解内核》

一种很有用的抽象,叫虚拟内存(virtual memory)。虚拟内存作为一种逻辑层,处于应用程序的内存请求与硬件内存管理单元(memory management unit,MMU)之间。虚拟内存有很多用途和优点:

·若干个进程可以并发低执行。

·应用程序所需内存大于可用物理内存时也可以运行。

·程序只有部分代码装入内存是进程可以执行它。

·允许每个进程访问可用物理内存的子集

·进程可以共享库函数或程序的一个单独内存映像

·程序是可重定位的,也就是说,可以把程序放在物理内存的任何地方。

·程序员可以编写与机器无关的代码,因为他们不必关心有关物理内存的组织结构。

虚拟内存子系统的主要成分是虚拟地址空间(virtual address space)的概念。进程所用的一组内存地址不同于物理内存地址。当进程使用一个虚拟地址时,内核和MMU协同定位其在内存中的实际物理位置。

         现在的cpu包含了能自动把虚拟地址转换成物理地址的硬件电路。为了达到这个目标,把可用ram划分成长度为4kb或者8kb的页框(page frame),并且引入一组页表来指定虚拟地址与物理地址之间的对应关系。这些电路使内存分配变得简单,因为这一块连续的虚拟地址请求可以通过分配一组非连续的物理地址页框而得到满足。

3,随机访问存储器(ram)的使用
         所有的cunix操作系统都将ram毫无疑义地划分为两部分,其中若干兆字节专门用于存放内核映像(也就是内核代码和内核静态数据结构)。ram的其余部分通常由虚拟内存系统来处理,并且用在以下三中可能的方面:

·满足内核对缓冲区、描述符及其他动态内核数据结构的请求。

·满足进程对一般内存区的请求及对文件内存映像的请求。

·借助于告诉缓存从磁盘及其他缓冲区设备获得较好的性能。


 

你可能感兴趣的:(LINUX)