URN Logo
UNIX Resources » Linux » China Linux Forum » C/C++编程版 » 25 » linux中怎么能将reserved以及commit内存分开呢?
announcement 声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
China Linux Forum(finished)
Linux Forum(finished)
FreeBSD China(finished)
linuxforum.net
  业界新闻与评论
  自由软件杂谈
  IT 人生
  Linux软件快递
  翻译作坊
  Linux图书与评论
  GNU Emacs/XEmacs
  Linux 中文环境和中文化
  Linux桌面与办公软件
  Linux 多媒体与娱乐版
  自由之窗Mozilla
  笔记本电脑上的Linux
  Gentoo
  Debian 一族
  网络管理技术
  Linux 安装与入门
  WEB服务器和FTP服务器
  域名服务器和邮件服务器
  Linux防火墙和代理服务器应用
  文件及打印服务器
  技术培训与认证
  Linux内核技术
  Linux 嵌入技术
  Linux设备驱动程序
  Linux 集群技术
  LINUX平台数据库
  系统和网络安全
  CPU 与 编译器
  系统计算研究所专栏
  Linux下的GUI软件开发
  C/C++编程版
  PHP 技 术
  Java&jsp技术
  Shell编程技术
  Perl 编 程
  Python 编 程
  XML/Web Service 技术
  永远的Unix
  FreeBSD世界
   
linux中怎么能将reserved以及commit内存分开呢?
 
 
 
 
 
 
 
 
 
Subject: linux中怎么能将reserved以及commit内存分开呢?
Author: charlyisme    Posted: 2005-09-23 10:18    Length: 548 byte(s)
[Original] [Print] [Top]
windows中有VirtualAlloc这种先申请虚拟地址空间(reserved)再根据需要提交(commit)
物理内存页面,也就是说比如reserved的空间不必须完全提交,而是根据需要提交。
linux下有这种内存分配模型么?

比如 cell[200][256][64];我用VirtualAlloc可以先申请虚拟地址空间,根据我访问到的再
提交部分成员的物理内存页面,全部分配的代价可以很大。(windows核心编程中有讲)
但是在linux下我用malloc申请时就肯定分配了物理内存页面的。

linux中怎么能象windows中VirtualAlloc那样将reserved内存以及commit内存分开呢?
[Original] [Print] [Top]
Subject: Re: linux中怎么能将reserved以及commit内存分开呢?
Author: teawater    Posted: 2005-09-23 10:53    Length: 116 byte(s)
[Original] [Print] [Top]
“但是在linux下我用malloc申请时就肯定分配了物理内存页面的。 "

这个观点是如何而来?
----
读了这么多年的书 还是觉得幼儿园好混
[Original] [Print] [Top]
Subject: Re: linux中怎么能将reserved以及commit内存分开呢?
Author: charlyisme    Posted: 2005-09-26 10:27    Length: 330 byte(s)
[Original] [Print] [Top]
to teawater:

malloc申请内存时会导致sys_brk()的调用,执行到do_brk()中make_pages_present()会对新区间(VMA)每个页面模拟一次缺页异常,在这里会对每个页面分配物理内存页面的。上面的新区间(VMA)或新建,或新合并的。

以上针对2.4内核而言。

不知道这样理解是否有问题,请teawater指点一下。
[Original] [Print] [Top]
Subject: Re: linux中怎么能将reserved以及commit内存分开呢?
Author: teawater    Posted: 2005-09-26 11:29    Length: 180 byte(s)
[Original] [Print] [Top]
惭愧惭愧 我也没有仔细阅读过这部分的代码 不过sys_brk这块我理解也是大概这么一套东西 当然得以有MMU为前提
malloc不是简单的调用sys_brk 是在vma不够的时候才调用 具体就得看glibc了
----
读了这么多年的书 还是觉得幼儿园好混
[Original] [Print] [Top]
Subject: Re: linux中怎么能将reserved以及commit内存分开呢?
Author: charlyisme    Posted: 2005-09-27 09:12    Length: 316 byte(s)
[Original] [Print] [Top]
to teawater:
“malloc不是简单的调用sys_brk 是在vma不够的时候才调用”

对,当然,如果vma够用的话就不会移动brk了。不过应该也是分配了物理页面的了。


回到问题本身上来,有没有办法将reserve与commit分开?就像win32的VrtualAlloc一样。


请教!
[Original] [Print] [Top]
Subject: Re: linux中怎么能将reserved以及commit内存分开呢?
Author: Atu    Posted: 2005-09-27 09:43    Length: 397 byte(s)
[Original] [Print] [Top]
> 但是在linux下我用malloc申请时就肯定分配了物理内存页面的。

Linux中malloc申请内存时,并不分配物理内存,而是在真正使用的时候才分配。
我不知道这是否就是你所说的意思。

但是,如果用数组,可能无法达到这种效果,数组与malloc的存储方式是不一样的。
不知道Windows的VirtualAlloc是否可以用于大数组,如cell[200][256][64]......

[Original] [Print] [Top]
Subject: Re: linux中怎么能将reserved以及commit内存分开呢?
Author: Atu    Posted: 2005-09-27 10:25    Length: 1,006 byte(s)
[Original] [Print] [Top]
> malloc申请内存时会导致sys_brk()的调用,执行到do_brk()中make_pages_present()
> 会对新区间(VMA)每个页面模拟一次缺页异常,
>在这里会对每个页面分配物理内存页面的。

你说的是指这段代码吗?

unsigned long do_brk(unsigned long addr, unsigned long len)
{
struct mm_struct * mm = current->mm;
struct vm_area_struct * vma, * prev;
unsigned long flags;
......
mm->total_vm += len >> PAGE_SHIFT;
if (flags & VM_LOCKED) {
mm->locked_vm += len >> PAGE_SHIFT;
make_pages_present(addr, addr + len);
}
return addr;
......
}


这里是要判断条件的,只有设置了VM_LOCKED标记的时候,才会调用make_pages_present()的。

Kernel Version is 2.4.20-8 (Redhat 9.0)
[Original] [Print] [Top]
Subject: Re: linux中怎么能将reserved以及commit内存分开呢?
Author: charlyisme    Posted: 2005-09-27 11:43    Length: 813 byte(s)
[Original] [Print] [Top]
>不知道Windows的VirtualAlloc是否可以用于大数组,如cell[200][256][64]......

对,可以的,这是<<windows核心编程>>的一个例子。

谢谢Atu的指点。

再请教一下:
1)cell[200][256][64]应该是栈上分配的吧?
如果是栈上分配,那么是否linux中全部分配了物理内存页面的?
记得好像栈操作也是通过缺页异常来分配物理页面的,用alloc_page来分配的。


2)
>Linux中malloc申请内存时,并不分配物理内存,而是在真正使用的时候才分配。
malloc如果是真正使用的时候才分配,那么相关代码是哪一部分?也是通过缺页异常么?


3)
>我不知道这是否就是你所说的意思。
我想请教一下如何cell[200][256][64]这种内存分配的reserve与commit分开?
[Original] [Print] [Top]
Subject: Re: linux中怎么能将reserved以及commit内存分开呢?
Author: Atu    Posted: 2005-09-27 14:16    Length: 1,893 byte(s)
[Original] [Print] [Top]
不好意思,我对Linux的内核以及系统底层的一些实现不很了解

我想一个简单的方法就是写一段程序测试一下

我的程序是这样的

#include <stdlib.h>
#include <stdio.h>

// char s[100 * 1024 * 1024];
void fun()
{
char s[100 * 1024 * 1024];
getchar();

for ( int i = 0; i < 100 * 1024 * 1024; i ++ )
s[i] = 0;
getchar();
}
int main()
{
fun();
// char *s = (char *)malloc(100 * 1024 * 1024);
// printf("s = %p ", s);
// getchar();
// for ( int i = 0; i < 100 * 1024 * 1024; i += 8 * 1024 )
// s[i] = 0;
// getchar();
}


注释的几段分别是不同情况的测试:全局数组;函数数组(栈);动态分配

运行程序的同时,通过free和ps axu命令检查系统剩余内存和程序使用内存情况

结果表明,在这三种情况中,在未实际访问该内存以前,物理内存被未被使用;
只是在实际使用该内存后,该内存才被使用。

我同时也测试了一8K为步长访问内存,结果也验证了我的猜测:实际物理内存使用量为大约50M。

至于malloc调用与分配物理内存与否,其实都是由Linux Kernel实现的,
我的理解是:
malloc只是调用了brk(2),调整了进程可以使用的地址边界,
在其后访问该内存区域的时候,内核会判断访问的地址是否超过该边界,
如果超出边界范围,就是segment fault;
否则,内核会分配真正的物理内存——如果需要的话。

至于你所说的reserved与commit,
我觉得粗糙一点的话,你可以不去管它,反正Kernel已经做得够好了

如果真的要节省一点内存的话,在数据结构和算法层次想办法可能更好一点
至少提高了可移植性。
[Original] [Print] [Top]
« Previous thread
难道标准库STDARG.H是错的?
C/C++编程版
25
Next thread »
线程问题: 请问下面这种情况如何进行异步处理?
     

Copyright © 2007 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
备案序号: 京ICP备05006143    webmaster: webmaster@unixresources.net
This page created on 2008-07-17 03:52:36, cost 0.054999113082886 ms.