如何让程序占用虚拟内存,而不占用实际内存

zlt982001 2005-05-31 10:05:22
请看这个网站上的一个软件:桌面日历秀
http://www.cfishsoft.com/

这个软件在运行时只占用 400多K的内存,虚拟内存占6M,是用Delphi写的
谁知道他的工作原理和使用了那些API
...全文
824 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
会思考的草 2005-07-27
  • 打赏
  • 举报
回复
VirualAlloc指定为COMMIT差不多就可以了。它只保留虚拟地址空间供将来使用。
tyb98032 2005-07-27
  • 打赏
  • 举报
回复
以下摘自《Programming Windows》

假设想实现一个电子表格应用程序,这个电子表格为2 0 0行x 256列。对于每一个单元格,
都需要一个C E L L D ATA结构来描述单元格的内容。若要处理这种二维单元格矩阵,最容易的方
法是在应用程序中声明下面的变量:
如果C E L L D ATA结构的大小是1 2 8字节,那么这个二维矩阵将需要6 553 600(200 x 256 x
1 2 8)个字节的物理存储器。对于电子表格来说,如果直接用页文件来分配物理存储器,那么
这是个不小的数目了,尤其是考虑到大多数用户只是将信息放入少数的单元格中,而大部分单
元格却空闲不用,因此显得有些浪费。内存的利用率非常低。
传统上,电子表格一直是用其他数据结构技术来实现的,比如链接表等。使用链接表,只
需要为电子表格中实际包含数据的单元格创建C E L L D ATA结构。由于电子表格中的大多数单元
格都是不用的,因此这种方法可以节省大量的内存。但是这种方法使得你很难获得单元格的内
容。如果想知道第5行第1 0列的单元格的内容,必须遍历链接表,才能找到需要的单元格,因
此使用链接表方法比明确声明的矩阵方法速度要慢。
虚拟内存为我们提供了一种兼顾预先声明二维矩阵和实现链接表的两全其美的方法。运用
虚拟内存,既可以使用已声明的矩阵技术进行快速而方便的访问,又可以利用链接表技术大大
节省内存的使用量。
如果想利用虚拟内存技术的优点,你的程序必须按照下列步骤来编写:
1) 保留一个足够大的地址空间区域,用来存放C E L L D ATA结构的整个数组。保留一个根
本不使用任何物理存储器的区域。
2) 当用户将数据输入一个单元格时,找出C E L L D ATA结构应该进入的保留区域中的内存
地址。当然,这时尚未有任何物理存储器被映射到该地址,因此,访问该地址的内存的任何企
图都会引发访问违规。
3) 就C E L L D ATA结构来说,只将足够的物理存储器提交给第二步中找到的内存地址(你
可以告诉系统将物理存储器提交给保留区域的特定部分,这个区域既可以包含映射到物理存储
器的各个部分,也可以包含没有映射到物理存储器的各个部分)。
4) 设置新的C E L L D ATA结构的成员。
现在物理存储器已经映射到相应的位置,你的程序能够访问内存,而不会引发访问违规。
这个虚拟内存技术非常出色,因为只有在用户将数据输入电子表格的单元格时,才会提交物理
存储器。由于电子表格中的大多数单元格是空的,因此大部分保留区域没有提交给它的物理存
储器。
虚拟内存技术存在的一个问题是,必须确定物理存储器在何时提交。如果用户将数据输入
一个单元格,然后只是编辑或修改该数据,那么就没有必要提交物理存储器,因为该单元格的
C E L L D ATA结构的内存在数据初次输入时就已经提交了。
另外,系统总是按页面的分配粒度来提交物理存储器的。因此,当试图为单个C E L L D ATA
结构提交物理存储器时(像上面的第二步那样),系统实际上提交的是内存的一个完整的页面。
这并不像它听起来那样十分浪费:为单个C E L L D ATA结构提交物理存储器的结果是,也要为附
近的其他C E L L D ATA结构提交内存。如果这时用户将数据输入邻近的单元格(这是经常出现的
情况),就不需要提交更多的物理存储器。
有4种方法可以用来确定是否要将物理存储器提交给区域的一个部分:
第1 5章在应用程序中使用虚拟内存计计357
下载
• 始终设法进行物理存储器的提交。每次调用Vi r t u a l A l l o c函数的时候,不要查看物理存储
器是否已经映射到地址空间区域的一个部分,而是让你的程序设法进行内存的提交。系
统首先查看内存是否已经被提交,如果已经提交,那么就不要提交更多的物理存储器。
这种方法最容易操作,但是它的缺点是每次改变C E L L D ATA结构时要多进行一次函数的
调用,这会使程序运行得比较慢。
• (使用Vi r t u a l Q u e r y函数)确定物理存储器是否已经提交给包含C E L L D ATA结构的地址空
间。如果已经提交了,那么就不要进行任何别的操作。如果尚未提交,则可以调用
Vi r t u a l A l l o c函数以便提交内存。这种方法实际上比第一种方法差,它既会增加代码的长
度,又会降低程序运行的速度(因为增加了对Vi r t u a l A l l o c函数的调用)。
• 保留一个关于哪些页面已经提交和哪些页面尚未提交的记录。这样做可以使你的应用程
序运行得更快,因为不必调用Vi r t u a l A l l o c函数,你的代码能够比系统更快地确定内存是
否已经被提交。它的缺点是,必须不断跟踪页面提交的信息,这可能非常简单,也可能
非常困难,要根据你的情况而定。
• 使用结构化异常处理( S E H)方法,这是最好的方法。S E H是一个操作系统特性,它使
系统能够在发生某种情况时将此情况通知你的应用程序。实际上可以创建一个带有异常
处理程序的应用程序,然后,每当试图访问未提交的内存时,系统就将这个问题通知应
用程序。然后你的应用程序便进行内存的提交,并告诉系统重新运行导致异常条件的指
令。这时对内存的访问就能成功地进行了,程序将继续运行,仿佛从未发生过问题一样。
这种方法是优点最多的方法,因为需要做的工作最少(也就是说要你编写的代码比较少),
同时,你的程序可以全速运行。关于S E H的全面介绍,请参见第2 3、2 4和2 5章。第2 5章
中的电子表格示例应用程序说明了如何按照上面介绍的方法来使用虚拟内存。
柯本 2005-06-01
  • 打赏
  • 举报
回复
最好不要用MFC类,更好的不用C++,直接用C调API/SDK
qrlvls 2005-06-01
  • 打赏
  • 举报
回复
VirtualAllocEx cannot reserve a reserved page. It can commit a page that is already committed. This means you can commit a range of pages, regardless of whether they have already been committed, and the function will not fail.

You can use VirtualAllocEx to reserve a block of pages and then make additional calls to VirtualAllocEx to commit individual pages from the reserved block. This enables a process to reserve a range of its virtual address space without consuming physical storage until it is needed.

The VirtualFreeEx function can decommit a committed page, releasing the page's storage, or it can simultaneously decommit and release a committed page. It can also release a reserved page, making it a free page.

sboom 2005-05-31
  • 打赏
  • 举报
回复
用原始API编写,尽量用全局变量,少用堆栈。设置成最优化编译。
zlt982001 2005-05-31
  • 打赏
  • 举报
回复
我当然知道要进行一些操作,现在我不是要讨论VC应该占多少内存,我只是想知道 我上面提的软件他是怎么工作的
newcore 2005-05-31
  • 打赏
  • 举报
回复
vc6.0编译一个什么也不做的exe也在不觉中包含了很多东西...
这个应该取决于vc6.0的编译器把,同样的代码,不同的编译器compile后的大小也是不同的。
zlt982001 2005-05-31
  • 打赏
  • 举报
回复
怎么将软件自体缩至400K左右,Vc的一个什么都不作的EXE也要使用1.2M内存
jerry 2005-05-31
  • 打赏
  • 举报
回复
其实可以用简单的办法实现. 创建一个足够大的临时文件,然后将数据写入到文件的适当位置就是了.

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧