在应用程序中使用虚拟内存(VirtualAlloc VirtualFree)

此虚拟内存非彼虚拟内存,此虚拟内存实际上指的是虚拟地址空间
LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的内存区域的地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的类型
DWORD flProtect // 该内存的初始保护属性
};
1.这个函数可以用来对虚拟地址空间进行分配(保留操作MEM_RESERVE)
2.这个函数可以把已经保留的虚拟地址提交到物理存储器(MEM_COMMIT)
3.这个函数可以使RAM上的内容无效(MEM_RESET)

这个函数的注意点
1.该函数会将传入lpAddress圆整为64KB(分配粒度)的倍数,然后通过返回值传一个基地址给你,也就是说该函数返回的值要么为NULL,要么为64KB的倍数
2.如果该函数调用失败,会直接返回NULL
3.当函数进行保留操作时,不管使用怎样的保护属性,都对提交的保护属性没影响,但是,若是想让系统高效运行,最好让保留操作和提交操作的保护属性一致
4.保留操作和提交操作可以同时进行,方法是设置flAllocationType=MEM_RESERVE|MEM_COMMIT
5.使用MEM_RESET标志可使RAM页面内容无效,防止系统占用已用内存时,把RAM写到硬盘的页文件,因为这个操作会降低系统的运行效率,但是经过我的测试,这个标志只在windows2000下有效,在windows xp 或者win7无效(所以这条可以不考虑)

BOOL VirtualFree(
LPVOID lpAddress, // 区域地址
SIZE_T dwSize, // 区域大小,字节
DWORD dwFreeType // 类型);
看名字都看得出来,这个函数时释放或者解除虚拟地址到物理存储器的映射
使用这个函数时只能释放区域的全部内存,但是收回物理存储器时却可不受此限制

我们来说说这个函数的应用
假如你有一个表格,为200行X256列,如果一个单元格的结构大小为128字节,大概需要6553600个字节的空间,这段内存分页的话大概也需要1600*4K,也就是需要1600个RAM页,但是可能我们只有几个单元格填入内容,可以说,内存的使用率极低
当然也有其他的方法,就是链表,用到一个单元格就申请相应的内存,然后连接到链表上,但是,这么做的话,不便于直观的得到每个单元格的内容,因为我们必须要遍历链表,现在有了虚拟地址空间,我们就可以尝试新的方法了
1.先申请保留200*256*128个字节的虚拟地址空间,当然这是一个二维的地址数组,比如p[200][256];
2.然后,假如第100行100列的单元格填入内容,我们就设法找到p[99][99]的虚拟内存地址,然后使用VirtualAlloc把该地址提交到物理存储器
3.当然就上面的步骤而言还需要做个内存检查(检查虚拟地址是否已经提交到物理存储器)
4.设置新的单元格数据结构的成员

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很好,这是一个关于内存管理的实验,包括了系统数据结构、内存分配和释放函数等内容。以下是具体步骤和源代码: 步骤一:建立一个控制台程序,查看系统物理内存大小、页文件大小、虚拟内存大小。 ``` #include <windows.h> #include <stdio.h> int main() { MEMORYSTATUS memstat; GlobalMemoryStatus(&memstat); printf("系统物理内存大小:%d MB\n", memstat.dwTotalPhys / 1024 / 1024); printf("页文件大小:%d MB\n", memstat.dwTotalPageFile / 1024 / 1024); printf("虚拟内存大小:%d MB\n", memstat.dwTotalVirtual / 1024 / 1024); return 0; } ``` 步骤二:使用VirtualAlloc()和malloc()分配一定数量的虚拟内存空间和物理内存空间,再次按1的要求查看相关内存参数。 ``` #include <windows.h> #include <stdio.h> #include <stdlib.h> int main() { MEMORYSTATUS memstat; GlobalMemoryStatus(&memstat); printf("系统物理内存大小:%d MB\n", memstat.dwTotalPhys / 1024 / 1024); printf("页文件大小:%d MB\n", memstat.dwTotalPageFile / 1024 / 1024); printf("虚拟内存大小:%d MB\n", memstat.dwTotalVirtual / 1024 / 1024); // 分配虚拟内存 LPVOID lpvMem = VirtualAlloc(NULL, 1024 * 1024 * 100, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (lpvMem == NULL) { printf("分配虚拟内存失败\n"); return -1; } // 分配物理内存 int *p = (int*)malloc(1024 * 1024 * 50); if (p == NULL) { printf("分配物理内存失败\n"); return -1; } GlobalMemoryStatus(&memstat); printf("分配后系统物理内存大小:%d MB\n", memstat.dwTotalPhys / 1024 / 1024); printf("分配后页文件大小:%d MB\n", memstat.dwTotalPageFile / 1024 / 1024); printf("分配后虚拟内存大小:%d MB\n", memstat.dwTotalVirtual / 1024 / 1024); return 0; } ``` 步骤三:使用VirtualFree()和free()释放步骤二分配的内存和虚拟内存,再次按1的要求查看相关内存参数。 ``` #include <windows.h> #include <stdio.h> #include <stdlib.h> int main() { MEMORYSTATUS memstat; GlobalMemoryStatus(&memstat); printf("系统物理内存大小:%d MB\n", memstat.dwTotalPhys / 1024 / 1024); printf("页文件大小:%d MB\n", memstat.dwTotalPageFile / 1024 / 1024); printf("虚拟内存大小:%d MB\n", memstat.dwTotalVirtual / 1024 / 1024); // 分配虚拟内存 LPVOID lpvMem = VirtualAlloc(NULL, 1024 * 1024 * 100, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (lpvMem == NULL) { printf("分配虚拟内存失败\n"); return -1; } // 分配物理内存 int *p = (int*)malloc(1024 * 1024 * 50); if (p == NULL) { printf("分配物理内存失败\n"); return -1; } GlobalMemoryStatus(&memstat); printf("分配后系统物理内存大小:%d MB\n", memstat.dwTotalPhys / 1024 / 1024); printf("分配后页文件大小:%d MB\n", memstat.dwTotalPageFile / 1024 / 1024); printf("分配后虚拟内存大小:%d MB\n", memstat.dwTotalVirtual / 1024 / 1024); // 释放虚拟内存 if (!VirtualFree(lpvMem, 0, MEM_RELEASE)) { printf("释放虚拟内存失败\n"); return -1; } // 释放物理内存 free(p); GlobalMemoryStatus(&memstat); printf("释放后系统物理内存大小:%d MB\n", memstat.dwTotalPhys / 1024 / 1024); printf("释放后页文件大小:%d MB\n", memstat.dwTotalPageFile / 1024 / 1024); printf("释放后虚拟内存大小:%d MB\n", memstat.dwTotalVirtual / 1024 / 1024); return 0; } ``` 步骤四:截图并完成实验报告。 步骤五:实验截图和总结。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值