免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2597 | 回复: 7
打印 上一主题 下一主题

帮忙看看这句话怎么理解( from man page of sbrk ) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-02-05 11:27 |只看该作者 |倒序浏览
NAME
       brk, sbrk - change data segment size

SYNOPSIS
       #include <unistd.h>;

       int brk(void *end_data_segment);

       void *sbrk(ptrdiff_t increment);

DESCRIPTION
       brk  sets  the  end  of  the  data  segment  to  the value specified by
       end_data_segment, when that value is reasonable, the system  does  have
       enough  memory  and  the process does not exceed its max data size (see
       setrlimit(2)).

       sbrk increments the program's data  space  by  increment  bytes.   sbrk
       isn't a system call, it is just a C library wrapper.  Calling sbrk with
       an increment of 0 can be used to find the current location of the  pro-
       gram break.

RETURN VALUE
       On  success,  brk returns zero, and sbrk returns a pointer to the start
       of the new area.  On error, -1 is returned, and errno is set to ENOMEM.


其中Calling sbrk with an increment of 0 can be used to find the current location of the  program break.

program break应该理解成什么???

论坛徽章:
0
2 [报告]
发表于 2004-02-05 12:21 |只看该作者

帮忙看看这句话怎么理解( from man page of sbrk )

自己up一下

论坛徽章:
0
3 [报告]
发表于 2004-02-05 13:21 |只看该作者

帮忙看看这句话怎么理解( from man page of sbrk )

我觉得整句话因该是“寻找当前的程序断点”

论坛徽章:
0
4 [报告]
发表于 2004-02-05 15:19 |只看该作者

帮忙看看这句话怎么理解( from man page of sbrk )

sbrk在linux中是用来改变data segment的尺寸的,这个prog break显然不该理解成为断点吧,data segment和break有什么关系?

论坛徽章:
0
5 [报告]
发表于 2004-02-05 15:40 |只看该作者

帮忙看看这句话怎么理解( from man page of sbrk )

拜托先学学数据编程!

论坛徽章:
0
6 [报告]
发表于 2004-02-06 09:30 |只看该作者

帮忙看看这句话怎么理解( from man page of sbrk )

请你来帮我解释一下什么叫数据编程,小生不才,弄了这么多年的unix,真就还没有听说过有个什么数据编程!

论坛徽章:
0
7 [报告]
发表于 2004-02-06 13:20 |只看该作者

帮忙看看这句话怎么理解( from man page of sbrk )

在UNIX/LINUX中,程序运行时动态内存以堆的方式来分配。
对程序而言,它使用的动态内存地址是虚拟内存,
代码用内存和数据用内存,一个从上往下,一个从下往上增长。
在LINUX,X86中,可用虚拟内存为0x00000000--0xffffffff;
对每一个进程都是一个独立的4GB空间。
但前面的1GB是内核用的,后面某一个位置才是程序运行时动态内存堆
的开始地址,你用多少它向上增多少。

比如语句  malloc(1024);

首先虚拟内存向上增长1024;//LINUX,kernel中do_brk();
然后系统使用mmap(),为这虚拟内存映射物理内存。
虚拟内存对物理内存的切入切出是另外的
理论上十分高深的东东,能写数米厚书而实际上就几行代码的东东,
你有时间看看linux内核代码中的mmap()。

说明几点,
程式分配虚拟内存也不是你要一个字节就给你一个字节,
而是你要一个字节给你一个页面,因为映射物理内存时只能以页为单位。
你要另一个字节时,它在这个页面的剩余空间给你。

注意大部份UNIX虚拟内存的使用是只增不减的。

  1. malloc(32 * 1024) --->;sbrk += 32 * 1024
  2. free()                  --->;sbrk 不减少。
  3. 但如如果再来一次
  4. malloc(32 * 1024) ---->;sbrk 也不增,使用原有空间.
复制代码

但对于LINUX来说它是要以内存的最大数收缩的;

  1. a = malloc(32 * 1024) -->;sbrk += 32 * 1024
  2. b = malloc(32 * 1024) -->;sbrk += 32 * 1024
  3. if(****){
  4.     free(b);   --->;sbrk -= 32 * 1024;
  5. }
  6. else{
  7.     free(a);   --->;sbrk 不减少。只是多了个空洞.
  8. }
复制代码



  1. /* linux kernel code */
  2. brk()
  3. /*
  4. *  sys_brk() for the most part doesn't need the global kernel
  5. *  lock, except when an application is doing something nasty
  6. *  like trying to un-brk an area that has already been mapped
  7. *  to a regular file.  in this case, the unmapping will need
  8. *  to invoke file system routines that need the global lock.
  9. */
  10. asmlinkage unsigned long sys_brk(unsigned long brk)
  11. {
  12.         unsigned long rlim, retval;
  13.         unsigned long newbrk, oldbrk;
  14.         struct mm_struct *mm = current->;mm;
  15.         down_write(&mm->;mmap_sem);
  16.         if (brk < mm->;end_code)
  17.                 goto out;
  18.         newbrk = PAGE_ALIGN(brk);
  19.         oldbrk = PAGE_ALIGN(mm->;brk);
  20.         if (oldbrk == newbrk)
  21.                 goto set_brk;
  22.      /******虚拟内存在这里收缩******/
  23.         /* Always allow shrinking brk. */
  24.         if (brk <= mm->;brk) {
  25.                 if (!do_munmap(mm, newbrk, oldbrk-newbrk))
  26.                         goto set_brk;
  27.                 goto out;
  28.         }
  29.         /* Check against rlimit.. */
  30.         rlim = current->;rlim[RLIMIT_DATA].rlim_cur;
  31.         if (rlim < RLIM_INFINITY && brk - mm->;start_data >; rlim)
  32.                 goto out;
  33.         /* Check against existing mmap mappings. */
  34.         if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
  35.                 goto out;
  36.         /* Check if we have enough memory.. */
  37.         if (!vm_enough_memory((newbrk-oldbrk) >;>; PAGE_SHIFT))
  38.                 goto out;
  39.         /* Ok, looks good - let it rip. */
  40.         if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk)
  41.                 goto out;
  42. set_brk:
  43.         mm->;brk = brk;
  44. out:
  45.         retval = mm->;brk;        /****这就是返回值*****/
  46.         up_write(&mm->;mmap_sem);
  47.         return retval;
  48. }
复制代码




在LINUX中sbrk(0)能返回比较精确的虚拟内存使用情况,
在SOLARIS/HP中sbrk(0)返回以页为单位的虚拟内存使用情况。


这样我们就可以用sbrk来得到程式当前使用内存情况。




我时常使用sbrk(0)来返回我的程式当前使用了多少内存。
main(){
    int start,end;
    start = sbrk(0);
    ....
    malloc(***);
    ....
    end = sbrk(0);
    printf("hello I used %d vmemory",end - start);
}

打字打得累死好像还是没有说明白sbrk,没时间打了。


综上所述,我把楼的的那句话
Calling sbrk with an increment of 0 can be used to find the current location of the program break
理解为使用sbrk(0)可以返回当前的程序所有使用的虚拟内存 达到/越过 了的地址。

break = 超过;超越

论坛徽章:
0
8 [报告]
发表于 2004-02-07 23:49 |只看该作者

帮忙看看这句话怎么理解( from man page of sbrk )

从字面理解,整段话的意思应该是:
sbrk把程序的数据段增加increment个字节。sbrk不是一个系统调用,而是一个C的库函数。用increment为0来调用sbrk函数,可以返回程序当前所停留的数据段位置。
jianyan的程序两个sbrk返回值相减得出占用内存情况,应该就是前后两个调用时,数据段当前指针相减,所以得出内存占用的大小。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP