由OJ提交结果联想到内存页面大小的一些小猜想
2012-05-21 00:50
232 查看
今天不知道抽起那条筋,去看了下之前买的二手的盗版的《APUE》。虽然对于Unix/Linux系统来说,我可以说是一概不知,但是看了前几章,感觉Linux和Windows都有不少相似的地方,当然不是指内核那些。好吧,其实我想说的不是这个。
其实想说的是,今晚提交完之后,看着那个提交结果,尤其是那个内存使用量,突然联想到了些什么。然后去翻一下自己AC过的题目,也是去看那个内存量。发现了一个规律,这些内存使用量均是4K的倍数。从这个4K,又想起上学期看的《操作系统原理》和《Windows核心编程 5th》里面曾经提到过系统使用的页面大小一般为4K或者为8K。于是果断去翻了一下核心编程(Orz,我没有关于操作系统原理的书),于是发现如下一段话:
“当应用程序预订地址空间中的一块区域时,系统会确保区域的大小正好是系统页面大小的整数倍。页面是一个内存单元,系统通过它来管理内存。与分配粒度相似,页面大小会根据不同的CPU而有所不同。X86和X64系统使用的页面大小为4KB,而IA-64系统使用的页面大小为8KB。如果应用程序试图预订一块大小为10KB的地址空间区域,那么系统会自动将该请求取整到页面大小的整数倍,然后用取整后的大小预订区域。这意味着在X86和X64系统中,系统会预订一块大小为12KB的区域,而在IA-64系统中,系统会预订一块
16KB的区域。”
如此一来,就可以解释为什么OJ显示的提交结果全部都是4KB的倍数了。因为内存的分配都是以页面大小为分配粒度,所以会取整到4K。
还有一个现象就是,就算我在程序开了很大的数组,如果我的OJ的测试数据根本用不到那么多空间,OJ显示的提交结果就是实际所用的内存使用了,而不是数组所占的字节大小。如果在这一种情况下,我调用了memset来对数组中所有元素赋值,那么OJ显示的提交结果就是接近我开的数组的大小。那么这种现象又是如何解释呢?
这又让我想起了核心编程里面提到的一个概念----“调拨”。原文是这样的:“为了使用所预订的地址空间区域,我们还必须物理存储器,并将存储器映射到所预订的区域。这个过程被称为调拨物理存储器。物理存储器始终都以页面为单位来调拨。我们通过调用VirtualAlloc函数来将物理存储器调拨给所预订的区域。当我们调拨物理存储器给区域时,并不需要给整个区域都调拨物理存储器。例如,我们可以预订一块大小为64KB的区域,然后把物理存储器拨给该区域中的第2个页面和第4个页面。当程序不再需要访问所预订区域中已调拨的物理存储器时,应该释放物理存储器,这个过程被称为撤销调拨物理存储器,通过调用VirtualFree函数来完成。”
不知道那个OJ系统是不是也是用这种方式来计算提交上来的程序内存使用量呢?但是,这里面又有一个问题,我的数组是开在全局作用域的,正确来说在编译的时候就已经确定下来到底需要多少字节的,如果OJ也是按照一般的编译步骤的话,应该也是得到这一个结果。接着我又去看了一下任务管理器这个程序的内存使用,发现这个数据和我计算的、OJ提交结果都不相同,而且差很远的说,这又是为什么呢?
其实想说的是,今晚提交完之后,看着那个提交结果,尤其是那个内存使用量,突然联想到了些什么。然后去翻一下自己AC过的题目,也是去看那个内存量。发现了一个规律,这些内存使用量均是4K的倍数。从这个4K,又想起上学期看的《操作系统原理》和《Windows核心编程 5th》里面曾经提到过系统使用的页面大小一般为4K或者为8K。于是果断去翻了一下核心编程(Orz,我没有关于操作系统原理的书),于是发现如下一段话:
“当应用程序预订地址空间中的一块区域时,系统会确保区域的大小正好是系统页面大小的整数倍。页面是一个内存单元,系统通过它来管理内存。与分配粒度相似,页面大小会根据不同的CPU而有所不同。X86和X64系统使用的页面大小为4KB,而IA-64系统使用的页面大小为8KB。如果应用程序试图预订一块大小为10KB的地址空间区域,那么系统会自动将该请求取整到页面大小的整数倍,然后用取整后的大小预订区域。这意味着在X86和X64系统中,系统会预订一块大小为12KB的区域,而在IA-64系统中,系统会预订一块
16KB的区域。”
如此一来,就可以解释为什么OJ显示的提交结果全部都是4KB的倍数了。因为内存的分配都是以页面大小为分配粒度,所以会取整到4K。
还有一个现象就是,就算我在程序开了很大的数组,如果我的OJ的测试数据根本用不到那么多空间,OJ显示的提交结果就是实际所用的内存使用了,而不是数组所占的字节大小。如果在这一种情况下,我调用了memset来对数组中所有元素赋值,那么OJ显示的提交结果就是接近我开的数组的大小。那么这种现象又是如何解释呢?
这又让我想起了核心编程里面提到的一个概念----“调拨”。原文是这样的:“为了使用所预订的地址空间区域,我们还必须物理存储器,并将存储器映射到所预订的区域。这个过程被称为调拨物理存储器。物理存储器始终都以页面为单位来调拨。我们通过调用VirtualAlloc函数来将物理存储器调拨给所预订的区域。当我们调拨物理存储器给区域时,并不需要给整个区域都调拨物理存储器。例如,我们可以预订一块大小为64KB的区域,然后把物理存储器拨给该区域中的第2个页面和第4个页面。当程序不再需要访问所预订区域中已调拨的物理存储器时,应该释放物理存储器,这个过程被称为撤销调拨物理存储器,通过调用VirtualFree函数来完成。”
不知道那个OJ系统是不是也是用这种方式来计算提交上来的程序内存使用量呢?但是,这里面又有一个问题,我的数组是开在全局作用域的,正确来说在编译的时候就已经确定下来到底需要多少字节的,如果OJ也是按照一般的编译步骤的话,应该也是得到这一个结果。接着我又去看了一下任务管理器这个程序的内存使用,发现这个数据和我计算的、OJ提交结果都不相同,而且差很远的说,这又是为什么呢?
相关文章推荐
- ASP中判断提交页面的数值,并且给予相应的结果的方法
- 你真的懂任务管理器中有关内存的参数Private(提交大小)和working set(工作设置)吗?
- Eclpise设置内存大小,解决登录项目页面时,内存不够问题
- Windows 7 里进程管理器里面的各列是什么含义?主要是和内存有关的内存-专用工作集,内存-工作集,内存-提交大小???
- form提交时,如果target=_blank,则会打开一个新页面,但是大小和位置无法控制,请问如何进行控制
- Windows 内存详解(二) windows任务管理器中的工作设置内存,内存专用工作集,提交大小详解
- windows任务管理器中的工作设置内存,内存专用工作集,提交大小详解
- windows任务管理器中的工作设置内存,内存专用工作集,提交大小详解
- 制作一个银行卡用户登录页面,提交后连接数据库进行登录验证,根据验证结果跳转到不同页面
- 通过XMLHTTP实现不刷新页面,提交并取回返回结果,非常有用!
- ZOJ 1205题解本来是一道大数运算水题,可是却纠结了很久,原因是没能真正读懂题意,要求的计算必须是一一对应输出即使前面出现几个0最后也要把前面的0输出,看别人用C++自己还是两个都提交了结果还是C占的内存少。
- ACM竞赛中提交题目时常见的一些结果
- [转载]windows任务管理器中的工作设置内存,内存专用工作集,提交大小详解
- 最近接触到的一些js调用window窗体的属性及通过JavaScript获取页面大小
- mongdb性能压力测试,随机查询,数据量1亿条记录 操作系统centos6.4x64位 从测试结果看,当mongodb将数据全部载入到内存后,查询速度根据文档的大小,性能瓶颈通常会是在网络流
- 你真的懂任务管理器中有关内存的参数Private(提交大小)和working set(工作设置)吗?
- 今天因为某些原因,把项目中的js代码更换了一些,结果不知道哪里改错了,页面跳转老是跳转不到指定页面
- c++中类对象分配内存大小与虚继承的一些问题
- 你真的懂任务管理器中有关内存的参数Private(提交大小)和working set(工作设置)吗?