三九宝宝网宝宝教育学龄段教育

更换策略,不要为难内存

11月17日 编辑 39baobao.com

[随时更换区域活动的材料,以适应主题活动的需要]新《纲要》中指出:教师应该成为幼儿学习活动的支持者、合作者、引导者。在活动中,教师是 催化剂 其工作是协助幼儿沿着兴趣的方向发展,而善于捕捉幼儿活动中发现的新兴趣,导向新...+阅读

在32位机上(64位也是一样的,但是空间大很多),一个进程可以分配到4GB的虚拟内存,当然,其中2G给了内核,剩下2GB有一些分给了代码段、数据段,最后剩下的就是给我们程序员用的了,这样看来,一个应用程序若硬生生的读取2GB左右的数据是一个极限了。

不过事实并非如此,只要利用虚拟内存技术有时还是可以读取的。

先简单说说windows虚拟内存的思路:

所谓虚拟内存,就是事实上可能还没有得到实际内存的内存,如果CPU要访问一个虚拟内存,哪么操作系统得首先判断这个虚拟内存有没有获得实际内存。如果有,那大可以大大方方的读取,甚至写数据。

但若如果没有,操作系统就必须在实际内存上找到一块地方,建立起与要读取虚拟内存的映射关系,这样就可以读取了。当然若是找不到这么多实际内存,那么可以一些暂时还没用到的实际内存放到更低一级的硬盘临时空间上,腾出空间来,再建立与虚拟内存的映射关系。

当然了,比如要读取2GB的数据,在1G内存上是无论如何也没法找到足够空间建立映射关系的。我们当然不可能一次性读取2GB数据,所以引入“页”这个概念,即每次虚拟内存射到实际内存上的时候,都是按页大小映射的,这个页大小,与CPU有关,在X86上一般是4KB。

说到这,读取大型数据的思路就出来了,我们可以先分配虚拟内存,等到我们读或者写当中的一些数据的时候,再分配实际内存,由于这些都是在内存这一级操作,效率远比读写数据的时候再从硬盘取出来的高。

windows API让我们轻松做到这一点。

VirtualAlloc,可以申请到一个虚拟内存,或者实际映射到实际内存的内存。我们可以先申请虚拟内存,等到真的要读取某处数据的时候,再申请实际内存(建立映射关系)。

详细可以看MSDN,下面给出一个示例代码:

&emspinclude

&emspinclude

&emspinclude

struct Sheet 我们要读取的数据结构

{

int nSize;

BOOL bVisible;

char big[1024 * 15];

std::string strText;

};

int main()

{

SYSTEM_INFO si;

GetSystemInfo(

DWORD dwPageSize = si.dwPageSize; 获得CPU读取的页大小

把页的单位转为字节(页的单位本来是KB,而我们的数据结构是按字节算的)

DWORD dwPageAsByte = dwPageSize * 1024;

以下dwOccupy获得一个数据结构所占的空间,由于是按页分配实际内存,这样所占空间并定是页的整数倍

DWORD dwMod = sizeof(Sheet) % dwPageAsByte;

DWORD dwOccupy = 0;

if (dwMod != 0)

{

dwOccupy = (sizeof(Sheet) / dwPageAsByte) * dwPageAsByte + dwPageAsByte;

}

else

{

dwOccupy = sizeof(Sheet);

}

申请虚拟内存,MEM_RESERVE表示不会和实际内存建立映射关系

LPVOID lpBaseAddr = VirtualAlloc(NULL, dwOccupy * 50, MEM_RESERVE, PAGE_READWRITE);

if (lpBaseAddr == NULL)

{

return 1;

}

__try

{

DWORD dwIndex = 0;

以下不断的输入要读取哪个数据,若此数据还有没有建立实际内存映射关系,那么建立

while(true)

{

std::cout >dwIndex;

根据输入的索引,计算出所要读取的数据结构所在地址,注意同样是按页分配的

LPVOID lpSheetAddr = (LPVOID)((DWORD)lpBaseAddr + (dwIndex - 1) * dwOccupy);

MEMORY_BASIC_INFORMATION mbi;

memset(

查询内存状态

if (VirtualQuery(lpSheetAddr,

if (lpAlloc == NULL)

{

std::cout strText = "hello world";

pSheet->bVisible = TRUE;

}

}

__except(EXCEPTION_EXECUTE_HANDLER)

{

}

释放内存

VirtualFree(lpBaseAddr, 0, MEM_RELEASE);

}

当然,这其中用到了一个影响效率的VirtualQuery函数,其实可以用异常处理手段提高效率的,留待以后再说。

还可以添加删除代码,一些数据不再用到的时候,可以把虚拟内存状态重新置为MEM_RESERVE,这样可以节省实际内存。

以下为关联文档:

这四件事,最好不要为难老师,需要家长来教育随着社会发展,竞争越来越激烈,孩子的教育也发生很大变化。以前的教育,学生、教师和学校参与即可,可如今若想孩子体智良好发展,学校之外,离不开家庭教育的支持。因为很多本事,学校根...

探索热煤炉更换为直接加热炉的综合分析安全措施主要有以下几方面: 1)对质量严格把关:加热炉的制造应符合《石油工业用加热炉安全规程》SY0031-95和《加热炉工程施工及验收规范》的规定。设计单位应取得《压力容器设计...

教孩子如何应对来自好朋友的左右为难你最好的朋友让你去做某些事情。当你告诉她,父母不允许你去做这样的事情时,她却说:“他们不会知道的”或是“我猜我对你没那么重要,所以你才不愿意去的”。你不想失去她这个朋友...

早上一年小学果然为难孩子终有体会:早上一年小学,果然很艰难。 作为一个各方面能力比较差的,腼腆的小女孩儿,8月底出生的女儿今年自愿地,快乐地走入了小学大门。虽然已经有了一定的心理准备,但妈妈对9月1日...

推荐阅读
图文推荐