首页 > 代码库 > mprotect() failed: Cannot allocate memory

mprotect() failed: Cannot allocate memory


遇到这个问题是在测试项目的性能时发现的,每个对象分配一页大小的空间然后mprotect() 保护起来,当系统分配3W多个页的时候会出现这个问题。
google到在一份邮件列表中也曾提到该问题.https://sourceware.org/ml/libc-help/2010-04/msg00026.html

摘抄部分如下:
----------------------------------------------------------------------------------------------------------------------
On Wed, 2010-04-21 at 01:05 +0200, Pawe? Sikora wrote:
> hi,

> i‘m trying to debug an ugly application with ElectricFence.
> in fact, on x86-64 box with 8GB ram and 16GB swap i‘m getting following error:

> "ElectricFence Exiting: mprotect() failed: Cannot allocate memory"

> the program has been compiled with gcc-4.5, glibc-2.11.1, kernel-2.6.32.
> did you ever come across such (kernel/glibc) limitations?

> here‘s a simple testcase which triggs -ENOMEM in mprotect().

You probably depleted the max map count, see:
  /proc/sys/vm/max_map_count

We have a limit on the number of maps you can have, those mprotect()

calls split you maps like crazy, see also /proc/$pid/maps.


eg. change your second test program to include something like:


  char buf[128];
  snprintf(buf, sizeof(buf), "cat /proc/%d/maps", (int)getpid());
  system(buf);

at the end after lowering your NN count to fit, and observe the result
of those mprotect() calls.

yes, that is the clue :)

the limit in /proc/sys/vm/max_map_count was set to 65530.
with `echo 128000 > /proc/sys/vm/max_map_count` the testcase passes.

----------------------------------------------------------------------------------------------------------------------
所以 解决方案是设置/proc/sys/vm/max_map_count为更大的值。

查看 max_map_count值:

more /proc/sys/vm/max_map_count
vm.max_map_count=128000直接写到/etc/sysctl.conf中,
然后执行

sysctl -p
或者直接执行 
echo 128000 > /proc/sys/vm/max_map_count
OK 到这里问题就解决了。总结一下原因:
proc文件系统给用户提供了很多内核信息帮助,使得用户可以通过修改内核参数达到提高系统性能的目的.

-----------------------------------------------------------------------------------------------------------------------------------------------------
wangtao@wangtao-Z87X-UD5H:/proc/sys/vm$ ls
block_dump                  legacy_va_layout           oom_dump_tasks
compact_memory              lowmem_reserve_ratio       oom_kill_allocating_task
dirty_background_bytes      max_map_count              overcommit_memory
dirty_background_ratio      memory_failure_early_kill  overcommit_ratio
dirty_bytes                 memory_failure_recovery    page-cluster
dirty_expire_centisecs      min_free_kbytes            panic_on_oom
dirty_ratio                 min_slab_ratio             percpu_pagelist_fraction
dirty_writeback_centisecs   min_unmapped_ratio         scan_unevictable_pages
drop_caches                 mmap_min_addr              stat_interval
extfrag_threshold           nr_hugepages               swappiness
extra_free_kbytes           nr_hugepages_mempolicy     vfs_cache_pressure
hugepages_treat_as_movable  nr_overcommit_hugepages    would_have_oomkilled
hugetlb_shm_group           nr_pdflush_threads         zone_reclaim_mode
laptop_mode                 numa_zonelist_order

---------------------------------------------------------------------------------
/proc/sys/vm 下每个文件的信息详见http://www.linuxinsight.com/proc_sys_vm_hierarchy.html
max_map_count :  This file contains the maximum number of memory map areas a process may have. Memory map areas are used as a side-effect of calling malloc, directly by mmap and mprotect, and also when loading shared libraries. While most applications need less than a thousand maps, certain programs, particularly malloc debuggers, may consume lots of them, e.g., up to one or two maps per allocation. The default value is 65536.





mprotect() failed: Cannot allocate memory