免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: congli
打印 上一主题 下一主题

一个进程可以分配多大的内存? [复制链接]

论坛徽章:
0
51 [报告]
发表于 2006-03-28 11:13 |只看该作者
补充一句:

PT2 malloc (大多数Linux): 如果size>256KB, 内存是mmap()得来的. 否则是用sbrk(). 这个值可编程修改.
Debian/Novell 的Hoard是64KB.

论坛徽章:
0
52 [报告]
发表于 2006-03-28 14:44 |只看该作者
原帖由 Alligator27 于 2006-3-28 11:13 发表
补充一句:

PT2 malloc (大多数Linux): 如果size>256KB, 内存是mmap()得来的. 否则是用sbrk(). 这个值可编程修改.
Debian/Novell 的Hoard是64KB.



FreeBSD的malloc仍然是基于brk/sbrk的,仅有一个用于管理的页面目录是用mmap分配的。

论坛徽章:
1
寅虎
日期:2013-09-29 23:15:15
53 [报告]
发表于 2006-03-28 16:08 |只看该作者
继续折腾,不过这次是KVA_PAGES保持系统默认,只修改MAXDISZ及DFLDSIZ,并不断增加,看看其"极限"是多少.
经过不断的折腾,向大家提供一些"有趣"的数据:
下面数据每次都是重新编译内核,重启后的数据.

测试环境:FreeBSD i386 5.4-Release-p13, RAM 1278MB.(5.4跟6.0的有点不一样)

1."2912"
options MAXDSIZ="(2912ULL*1024*1024)"
options DFLDSIZ="(2912ULL*1024*1024)"


结果1:
Allocated 2911 MB total.


结果2:
total address space : max = 4095M
max data segment : max = 2912M
max stack segment : max = 64M


2."2920"
options MAXDSIZ="(2920ULL*1024*1024)"
options DFLDSIZ="(2920ULL*1024*1024)"


结果1:
Allocated 2919 MB total.


结果2:
total address space : max = 4095M
max data segment : max = 2920M
max stack segment : max = 64M


结果3:(make kernel)
virtual memory exhausted: Cannot allocate memory



3."2928"
options MAXDSIZ="(2928ULL*1024*1024)"
options DFLDSIZ="(2928ULL*1024*1024)"


结果1:
Allocated 2927 MB total.


结果2:
total address space : max = 4095M
max data segment : max = 2928M
max stack segment : max = 64M


结果3:(make kernel)
virtual memory exhausted: Cannot allocate memory


4."2934"
options MAXDSIZ="(2934ULL*1024*1024)"
options DFLDSIZ="(2934ULL*1024*1024)"


结果1:
Allocated 1531 MB total.


结果2:
total address space : max = 4095M
max data segment : max = 2934M
max stack segment : max = 64M


结果3:(启动过程中,开始有服务出错)
Initial i386 initialization:.
Additional ABI support: linux/compat/linux/sbin/ldconfig: Cannot mmap file /lib/libdb-4.0.so.

/compat/linux/sbin/ldconfig: Cannot mmap file /usr/lib/libdb-4.0.so.

/compat/linux/sbin/ldconfig: Cannot mmap file /usr/lib/libdb_cxx-4.0.so.

.
Starting cron.
Local package initialization:Starting compat4x.
Starting apache22.
httpd: Syntax error on line 83 of /usr/local/etc/apache22/httpd.conf: Cannot load /usr/local/libexec/apache22/mod_ssl.so into server: /lib/libcrypto.so.3: mmap
of entire address space failed: Cannot allocate memory
cups: started scheduler.
Starting cvs pserver chroot wrapper: cvsd.
Starting cvsupd.

/libexec/ld-elf.so.1: /lib/libc.so.5: mmap of entire address space failed: Cannot allocate memory



结果4:(make kernel)
--------------------------------------------------------------
>>> stage 2.3: build tools
--------------------------------------------------------------
cd /usr/obj/usr/src/sys/PF;  MAKESRCPATH=/usr/src/sys/dev/aic7xxx/aicasm  make -DNO_CPU_CFLAGS -f /usr/src/sys/dev/aic7xxx/aicasm/Makefile
Warning: Object directory not changed from original /usr/obj/usr/src/sys/PF
cc -O -pipe -nostdinc -I/usr/include -I. -I/usr/src/sys/dev/aic7xxx/aicasm  -c /usr/src/sys/dev/aic7xxx/aicasm/aicasm.c
virtual memory exhausted: Cannot allocate memory
*** Error code 1


5."2935"
options MAXDSIZ="(2935ULL*1024*1024)"
options DFLDSIZ="(2935ULL*1024*1024)"


结果1:
Allocated 1195 MB total.


结果2:
total address space : max = 4095M
max data segment : max = 2935M
max stack segment : max = 64M


结果3:(dmesg)
Initial i386 initialization:.
Additional ABI support: linux/compat/linux/sbin/ldconfig: Cannot mmap file /lib/libdb-4.0.so.

/compat/linux/sbin/ldconfig: Cannot mmap file /usr/lib/libdb-4.0.so.

/compat/linux/sbin/ldconfig: Cannot mmap file /usr/lib/libdb_cxx-4.0.so.

.
Starting cron.
Local package initialization:Starting compat4x.
Starting apache22.
httpd: Syntax error on line 83 of /usr/local/etc/apache22/httpd.conf: Cannot load /usr/local/libexec/apache22/mod_ssl.so into server: /usr/lib/libssl.so.3: mmap of entire address space failed: Cannot allocate memory
cups: started scheduler.
Starting cvs pserver chroot wrapper: cvsd.
Starting cvsupd.

/libexec/ld-elf.so.1: /usr/local/lib/libiconv.so.3: mmap of entire address space failed: Cannot allocate memory



结果4:(make kernel)
--------------------------------------------------------------
>>> stage 2.3: build tools
--------------------------------------------------------------
cd /usr/obj/usr/src/sys/PF;  MAKESRCPATH=/usr/src/sys/dev/aic7xxx/aicasm  make -DNO_CPU_CFLAGS -f /usr/src/sys/dev/aic7xxx/aicasm/Makefile
Warning: Object directory not changed from original /usr/obj/usr/src/sys/PF
cc -O -pipe -nostdinc -I/usr/include -I. -I/usr/src/sys/dev/aic7xxx/aicasm  -c /usr/src/sys/dev/aic7xxx/aicasm/aicasm.c
virtual memory exhausted: Cannot allocate memory
*** Error code 1



6."2936"
options MAXDSIZ="(2936ULL*1024*1024)"
options DFLDSIZ="(2936ULL*1024*1024)"


结果1:
Allocated 859 MB total.


结果2:
total address space : max = 4095M
max data segment : max = 2936M
max stack segment : max = 64M


结果3:(dmesg)
Initial i386 initialization:.
Additional ABI support: linux/compat/linux/sbin/ldconfig: Cannot mmap file /lib/libdb-4.0.so.

/compat/linux/sbin/ldconfig: Cannot mmap file /usr/lib/libdb-4.0.so.

/compat/linux/sbin/ldconfig: Cannot mmap file /usr/lib/libdb_cxx-4.0.so.

.
Starting cron.
Local package initialization:Starting compat4x.
Starting apache22.
/libexec/ld-elf.so.1: /usr/local/lib/libdb-4.2.so.2: mmap of entire address space failed: Cannot allocate memory
cups: started scheduler.
Starting cvs pserver chroot wrapper: cvsd.
Starting cvsupd.

Starting SAMBA: removing stale tdbs :
/var/db/samba/messages.tdb
/var/db/samba/unexpected.tdb
Starting nmbd.
/libexec/ld-elf.so.1: /lib/libcrypto.so.3: mmap of entire address space failed:
Cannot allocate memory
Starting smbd.
/libexec/ld-elf.so.1: /usr/local/lib/compat/pkg/libgnutls.so.12: mmap of entire
address space failed: Cannot allocate memory
.


结果4:(make kernel)
--------------------------------------------------------------
>>> stage 2.3: build tools
--------------------------------------------------------------
cd /usr/obj/usr/src/sys/PF;  MAKESRCPATH=/usr/src/sys/dev/aic7xxx/aicasm  make -DNO_CPU_CFLAGS -f /usr/src/sys/dev/aic7xxx/aicasm/Makefile
Warning: Object directory not changed from original /usr/obj/usr/src/sys/PF
cc -O -pipe -nostdinc -I/usr/include -I. -I/usr/src/sys/dev/aic7xxx/aicasm  -c /usr/src/sys/dev/aic7xxx/aicasm/aicasm.c
virtual memory exhausted: Cannot allocate memory
*** Error code 1


7."2937"
options MAXDSIZ="(2937ULL*1024*1024)"
options DFLDSIZ="(2937ULL*1024*1024)"



结果1:
Allocated 523 MB total.


结果2:
total address space : max = 4095M
max data segment : max = 2937M
max stack segment : max = 64M


结果3:(dmesg)
Starting sshd.
/libexec/ld-elf.so.1: /lib/libc.so.5: mmap of entire address space failed: Cannot allocate memory
/libexec/ld-elf.so.1: /lib/libc.so.5: mmap of entire address space failed: Cannot allocate memory
/libexec/ld-elf.so.1: /lib/libc.so.5: mmap of entire address space failed: Cannot allocate memory
Initial i386 initialization:.
Additional ABI support: linuxem0: Link is up 100 Mbps Full Duplex
/compat/linux/sbin/ldconfig: Cannot mmap file /lib/libdb-4.0.so.

/compat/linux/sbin/ldconfig: Cannot mmap file /usr/lib/libdb-4.0.so.

/compat/linux/sbin/ldconfig: Cannot mmap file /usr/lib/libdb_cxx-4.0.so.

.
Starting cron.
Local package initialization:Starting compat4x.
Starting apache22.
/libexec/ld-elf.so.1: /lib/libc.so.5: mmap of entire address space failed: Cannot allocate memory
/libexec/ld-elf.so.1: /usr/local/lib/libiconv.so.3: mmap of entire address space failed: Cannot allocate memory
cups: unable to start scheduler.
Starting cvs pserver chroot wrapper: cvsd.
Starting cvsupd.

Starting SAMBA: removing stale tdbs :
Starting nmbd.
/libexec/ld-elf.so.1: /lib/libc.so.5: mmap of entire address space failed: Cannot allocate memory
Starting smbd.
ELF interpreter /libexec/ld-elf.so.1 not found
Abort trap
.


结果4:(make kernel)
--------------------------------------------------------------
>>> stage 2.3: build tools
--------------------------------------------------------------
cd /usr/obj/usr/src/sys/PF;  MAKESRCPATH=/usr/src/sys/dev/aic7xxx/aicasm  make -DNO_CPU_CFLAGS -f /usr/src/sys/dev/aic7xxx/aicasm/Makefile
Warning: Object directory not changed from original /usr/obj/usr/src/sys/PF
cc -O -pipe -nostdinc -I/usr/include -I. -I/usr/src/sys/dev/aic7xxx/aicasm  -c /usr/src/sys/dev/aic7xxx/aicasm/aicasm.c
virtual memory exhausted: Cannot allocate memory
*** Error code 1


结果5:(系统启动后,ttyv0显示该信息)
Mar 28 13:09:41 FreeBSD init: getty repeating too quickly on port /dev/ttyv8, sleeping 30 secs



8."2938"
options MAXDSIZ="(2938ULL*1024*1024)"
options DFLDSIZ="(2938ULL*1024*1024)"


结果:
能启动系统,出现login提示符,输入用户及密码,显示motd信息后,马上自动退出,返回login提示符.返回login提示前屏幕显示:/libexec/ld-elf.so.1:/lib/libc.so.5:mmap of entire address space faild:Cannot allocate memory


9."2939"
options MAXDSIZ="(2939ULL*1024*1024)"
options DFLDSIZ="(2939ULL*1024*1024)"


结果:
进入单用户模式,但不能登录,屏幕显示:/libexec/ld-elf.so.1:/lib/libc.so.5:mmap of entire address space faild:Cannot allocate memory


10."2940"
options MAXDSIZ="(2940ULL*1024*1024)"
options DFLDSIZ="(2940ULL*1024*1024)"


结果:panic
init died (signal 0,  exit 1)
panic : Going nowhere without my init


P.S.
结果1小程序:
  1.       1 #include <stdio.h>
  2.       2 #include <stdlib.h>
  3.       3
  4.       4 int main(){
  5.       5     int MB = 0;
  6.       6     while(malloc(1 << 20)) ++MB;
  7.       7     printf("Allocated %d MB total.\n", MB);
  8.       8 }
复制代码

结果2小程序:
  1.       1 #include <sys/types.h>
  2.       2 #include <sys/time.h>
  3.       3 #include <sys/resource.h>
  4.       4
  5.       5 int main(void){
  6.       6
  7.       7     struct rlimit limit;
  8.       8     if (getrlimit(RLIMIT_AS, &limit) == 0)
  9.       9         printf("total address space : max = %uM\n", ((unsigned int)limit.rlim_max)/(1024*1024));
  10.      10
  11.      11     if (getrlimit(RLIMIT_DATA, &limit) == 0)
  12.      12         printf("max data segment : max = %uM\n", ((unsigned int)limit.rlim_max)/(1024*1024));
  13.      13
  14.      14     if (getrlimit(RLIMIT_STACK, &limit) == 0)
  15.      15         printf("max stack segment : max = %uM\n", ((unsigned int)limit.rlim_max)/(1024*1024));
  16.      16
  17.      17 }
复制代码

[ 本帖最后由 congli 于 2006-3-28 21:07 编辑 ]

论坛徽章:
1
寅虎
日期:2013-09-29 23:15:15
54 [报告]
发表于 2006-03-28 16:27 |只看该作者
从"2912"启动,虽然可以make kernel,可以进入gnome2,但打不开firefox,没有任何出错信息,就是打不开.

论坛徽章:
0
55 [报告]
发表于 2006-03-28 16:43 |只看该作者
原帖由 gvim 于 2006-3-28 10:15 发表


我昨天在NetBSD上试了malloc(1024),没有出现你说的现象。



呵呵,我是在redhat 4.1 下, freebsd没有测试机,不敢在生产的机上搞, 程序占完所有内存和swap后就被操作系统自动KILL了, malloc(1 <<20)就不会出现这种情况

论坛徽章:
0
56 [报告]
发表于 2006-03-28 17:14 |只看该作者
原帖由 congli 于 2006-3-28 16:08 发表
继续折腾,不过这次是KVA_PAGES保持系统默认,只修改MAXDISZ及DFLDSIZ,并不断增加,看看其"极限"是多少.
经过不断的折腾,向大家提供一些"有趣"的数据:
下面数据每次都是重新编译内核,重启后的 ...



辛苦辛苦!

从试验结果来看,的确是随着数据段的逐渐增长,mmap的生存空间被不断压缩,使得基于mmap的各种库陆续出现分配不到空间的情况,最终导致系统启动失败。

另外,在2934M之前,实际malloc得到的空间是随着数据段上限的增长而增长的,但从2934M开始,实际malloc得到的空间却呈急速下降趋势。这种下降是有规律的,分析数字可知,mmap的生存空间每缩小1M,实际malloc得到的空间就减少336M。这个现象可以从FreeBSD的malloc的实现方式上来解释。

我在前面已经提到,FreeBSD的malloc仍然是基于brk/sbrk的,只不过它和内核之间的内存交易的粒度是页面而已。malloc会专门为它所管理的页面维护一个页面目录的结构,这个结构的空间就是用mmap生成的。这个页面目录空间对于整个malloc管理的空间而言可谓是牵一发而动全身,这儿少分配了一点,就会导致malloc得到的空间少很多。

在前面的试验中,我们不断地执行malloc操作,相应地,malloc也会逐渐通过mmap来扩展存放页面目录的空间。随着我们不断地调整内核参数,mmap的生存空间被逐步压缩,总有一个时刻会导致malloc扩展页面目录空间失败,于是就会出现实际malloc得到的内存急剧减少的现象。随着mmap生存空间的进一步压缩,可由mmap分配给页面目录的空间进一步减少,于是实际malloc得到的内存也就进一步减少了。无论是从试验数据来说,还是从前面的分析来说,这种因mmap分配页面目录空间失败而导致的实际malloc得到的空间减少的现象都呈现出一种线性的关系。至于336这个具体数字的解释,在进一步阅读malloc源代码之后应该就可以给出了。

论坛徽章:
1
寅虎
日期:2013-09-29 23:15:15
57 [报告]
发表于 2006-03-28 17:28 |只看该作者
原帖由 雨丝风片 于 2006-3-28 17:14 发表



辛苦辛苦!

从试验结果来看,的确是随着数据段的逐渐增长,mmap的生存空间被不断压缩,使得基于mmap的各种库陆续出现分配不到空间的情况,最终导致系统启动失败。

另外,在2934M之前,实际mall ...

呵~~
PFPF

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
58 [报告]
发表于 2006-03-28 18:26 |只看该作者
辛苦congli老大了。风雨的解释我还要再想想 ~_~

恩,过段时间看看NetBSD的UVM和FreeBSD的VM到底有什么不同。
NetBSD修改MAXDSIZ之后,至少可以启动,可以正常运行程序。而且,好像,我后面编译内核时使用的内核就已经将MAXDSIZ调整到3*1024*1024*1024之后的值。(我记得安装之后没有恢复过)
从这个单方面说,难道UVM模型真比FB采用的模型优秀些?
呵呵,有意思

论坛徽章:
0
59 [报告]
发表于 2006-03-28 19:05 |只看该作者
原帖由 gvim 于 2006-3-28 18:26 发表
恩,过段时间看看NetBSD的UVM和FreeBSD的VM到底有什么不同。
NetBSD修改MAXDSIZ之后,至少可以启动,可以正常运行程序。而且,好像,我后面编译内核时使用的内核就已经将MAXDSIZ调整到3*1024*1024*1024之后的值。(我记得安装之后没有恢复过)
从这个单方面说,难道UVM模型真比FB采用的模型优秀些?
呵呵,有意思


我觉得,从目前来看这里还涉及不到NB的UVM和FB的VM孰优孰劣的问题,而仅仅是一个进程的地址空间如何分布以及malloc如何实现的问题。NetBSD的malloc和FreeBSD的malloc出自一人,所以,两者表现差异的原因可能就是进程的地址空间分布了。

我在前面曾经怀疑过NetBSD的进程地址空间布局和Linux是一样的,即mmap空间从高向低长。今天查了一下NetBSD的文档,证实了我的想法:
【NetBSD Documentation: UVM, the new Virtual Memory system】
What is ``top down'' memory allocation?
This rearranges mmap(2)'ed memory allocations that don't request a specific address such that they start directly below the stack and work from the top down, instead of from the middle upwards. By doing this, the area of space reserved for heap growth and the area of space reserved for mmap(2)'ed allocations are merged, meaning that the heap can grow larger, or a process can mmap more or larger objects. The kernel still uses the traditional ``bottom up'' scheme for its internal memory management.


这里说的很清楚,NetBSD的mmap空间现在已经改成了从堆栈下面向下生长,而不是像原来那样从中间向上生长了。而且这里还点明了这样做的目的就是让heap或mmap有更大的生存空间。只不过内核仍然使用的是传统的自底向上的内存管理方案。

联系到我在前面帖子里画出的FreeBSD和Linux进程地址空间布局的示意图,就可以看出NetBSD的内存布局是和Linux一样的,Linux能够直接malloc到3G多,NetBSD自然也可以。

[ 本帖最后由 雨丝风片 于 2006-3-28 19:18 编辑 ]

论坛徽章:
0
60 [报告]
发表于 2006-03-28 22:20 |只看该作者
malloc 是在用户空间, 不会管理页面. 那是kernel的事.

我试了一下, Linux/AIX的mmap是由下向上的, Solaris/HP-UX与BSDs相似, 由上向下. (BSDs我没有机器试, 以上面贴的Document说.)

我的测试程序及结果如下.



  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <errno.h>
  5. #include <sys/mman.h>

  6. int main(void)
  7. {
  8.     char *p;

  9.     size_t pgsize = ::sysconf(_SC_PAGE_SIZE);
  10.     size_t size = 2*pgsize;

  11.     for(int i=0; i<10; i++)
  12.     {
  13.                 p = (char*) ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  14.                 if (!p)
  15.                 {
  16.                         fprintf(stderr, "Failed: mmap size=%ld", size);
  17.                         exit(errno);
  18.                 }
  19.                 printf("p(%d) = 0x%lx\n", i, p);
  20.         }

  21.     return 0;
  22. }

复制代码



  1. ======== RedHat AS 3 / x86_64 ==========
  2. p(0) = 0x2a9566d000
  3. p(1) = 0x2a95670000
  4. p(2) = 0x2a95672000
  5. p(3) = 0x2a95674000
  6. p(4) = 0x2a95676000
  7. p(5) = 0x2a95678000
  8. p(6) = 0x2a9567a000
  9. p(7) = 0x2a9567c000
  10. p(8) = 0x2a95d2c000
  11. p(9) = 0x2a95d2e000
  12. ======== Solaris / sparc ==========
  13. p(0) = 0xff160000
  14. p(1) = 0xff030000
  15. p(2) = 0xff020000
  16. p(3) = 0xff010000
  17. p(4) = 0xff000000
  18. p(5) = 0xfeff0000
  19. p(6) = 0xfefe0000
  20. p(7) = 0xfefd0000
  21. p(8) = 0xfefc0000
  22. p(9) = 0xfefb0000
  23. ======== HP-UX / IA64 ==========
  24. p(0) = 0x7efb4000
  25. p(1) = 0x7efb2000
  26. p(2) = 0x7efb0000
  27. p(3) = 0x7efae000
  28. p(4) = 0x7efac000
  29. p(5) = 0x7efaa000
  30. p(6) = 0x7efa8000
  31. p(7) = 0x7efa6000
  32. p(8) = 0x7efa4000
  33. p(9) = 0x7efa2000
  34. ======== AIX / PPC ==========
  35. p(0) = 0x30000000
  36. p(1) = 0x30002000
  37. p(2) = 0x30004000
  38. p(3) = 0x30006000
  39. p(4) = 0x30008000
  40. p(5) = 0x3000a000
  41. p(6) = 0x3000c000
  42. p(7) = 0x3000e000
  43. p(8) = 0x30010000
  44. p(9) = 0x30012000
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP