搜索
查看: 4595|回复: 42

揭穿号称内存占用极低的软件的诡计 - 正在用所谓优化版股软的最好来看下 BY 深男大盗

[复制链接]

签到天数: 1 天

发表于 2007-12-26 20:36 | 显示全部楼层

揭穿号称内存占用极低的软件的诡计 - 正在用所谓优化版股软的最好来看下 BY 深男大盗

来自:MACD论坛(bbs.shudaoyoufang.com) 作者:RegKiller 浏览:4595 回复:42

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
建议正在使用所谓内存优化版股软件的朋友都好好看看本贴,这是从专业程序员角度来说的,当然,最终的结果就是你也许正在加速老化你的硬盘。

本文其实也是为什么我一直不去给我发布的软件做内存优化的原因。


转贴,原文地址:http://x.discuz.net/474603/viewspace_43103.html

物理内存和虚拟内存

物理内存,在应用中,自然是顾名思义,物理上,真实的插在板子上的内存是多大就是多大了.看机器配置的时候,看的就是这个物理内存.

如果执行的程序很大或很多,就会导致物理内存消耗殆尽.为了解决这个问题,Windows中运用了虚拟内存技术,即拿出一部分硬盘空间来充当内存使用,当内存占用完时,电脑就会自动调用硬盘来充当内存,以缓解内存的紧张.

一个程序,不可避免地要用到虚拟内存,因为不频繁执行或者已经很久没有执行的代码,没有必要留在物理内存中,只会造成浪费;放在虚拟内存中,等执行这部分代码的时候,再调出来.
Windows 的任务管理器可以帮助我们看到进程的虚拟内存.调出任务管理器,点击菜单“查看”-“选择列”,在出现的窗口中,钩上“虚拟内存大小”,如下

0001.gif

点“确定”,这个时候,进程列表中已经显示各进程的虚拟内存大小

0002.gif

一个程序到底应该使用多少虚拟内存呢?不一定,但是应该以恰到好处的符合虚拟内存原本作用为最好.

下面将揭穿表面看起来调用了大量图片、大量运行库的程序,为什么才“占用”不到 1 MB 的内存的诡计.

原来是 SetProcessWorkingSetSize 函数

MSDN 对该函数的表述(翻译):使用这个函数来设置应用程序最小和最大的运行空间,只会保留需要的内存.当应用程序被闲置或系统内存太低时,操作系统会自动调用这个机制来设置应用程序的内存.应用程序也可以使用 VirtualLock 来锁住一定范围的内存不被系统释放;当你加大运行空间给应用程序,你能够得到的物理内存取决于系统,这会造成其他应用程序降低性能或系统总体降低性能,这也可能导致请求物理内存的操作失败,例如:建立 进程,线程,内核池,就必须小心的使用该函数.

也就是说,该函数不是节省内存,而是强制把进程的物理内存搬到虚拟内存中.

另外有一些资料上说,该函数“将有可能导致缺页中断,严重影响性能”.
函数原型:
BOOL SetProcessWorkingSetSize(
HANDLE hProcess,
SIZE_T dwMinimumWorkingSetSize,
SIZE_T dwMaximumWorkingSetSize
);
我们用 VB 来做这么一个简单的例子,是程序占用 300 KB 内存吧.

建立一个标准的 VB 工程,在 Form1 中放置一个 Timer1 ,把 Interval 属性设置为 1000 (即 1 秒).然后在代码编辑框中输入以下代码:
  1. Private Declare Function SetProcessWorkingSetSize Lib "kernel32" (ByVal hProcess As Long, ByVal dwMinimumWorkingSetSize As Long, ByVal dwMaximumWorkingSetSize As Long) As Long
  2. Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
  3. Private Sub Timer1_Timer()
  4. SetProcessWorkingSetSize GetCurrentProcess(), 50000, 100000
  5. End Sub
复制代码
然后生成 工程1.exe,执行,调出任务管理器查看,发现内存占用才 320 KB.如果把定时器关闭,这进程的内存一般 4 MB左右.
必须定时执行该函数,否则虚拟内存会慢慢被调出来,恢复原来的内存大小.
如果要使一个本来需要占用大量内存的程序减低到几百 KB ,使用同样的方法即可.

诡计带来的危害

如果 SetProcessWorkingSetSize 函数被正常使用,是非常有用处的.但是为了蒙骗用户的眼睛,每秒,甚至几十毫秒就把大量内存往虚拟内存里面压,就会带来无可预计的危害.看看这篇文章怎么说:“因为他只是暂时的将应用程序占用的内存移至虚拟内存,一旦,应用程序被激活或者有操作请求时,这些内存又会被重新占用.如果你强制使用该方法来设置程序占用的内存,那么可能在一定程度上反而会降低系统性能,因为系统需要频繁的进行内存和硬盘间的页面交换.”.

没错,如果你使用了这类软件,意味着你的硬盘将每秒将 I/O 大量数据;硬盘的磁针将拼命旋转...(当然硬盘磁针不可能不旋转^_^,只是选择得更厉害而已).

不是说 BT 很伤内存吗?不然,因为现在大多 BT 软件都有缓存技术.且看 Bitcomet 官方对缓存技术的说明:“传统BT高速下载时硬盘会响得很厉害,这是大量的随机读取造成的.... BitComet可以由用户设置缓存大小.... 可以明显地看出牺牲一小部分内存作缓存对硬盘的保护作用.”

是不是有种心寒的感觉?一类软件宁愿牺牲内存,也要减少保护硬盘;而另外一类软件,却为了欺骗用户,让CPU、硬盘更加奔波......

抓一个凶手

这类软件不少,我以其中一个桌面工具为例,揭穿它的假面具(不点名字了).运行该软件后,随意操作一下,然后打开进程管理器,把虚拟内存列调出来。

OK,20 MB 虚拟内存,而只有 632 KB 物理内存.细心的你会发现,大概每 1 秒,该行都有闪烁的感觉,没错,这正是每秒调用 SetProcessWorkingSetSize 的结果.另外,我们打开 Norton Process Viewer ,查看该进程的 CPU 占用情况,可以看到,就算没有操作该软件,但是每秒,都有 3% 的CPU占用起伏(虽然这并不能说明什么).另外,内存框中可以看到物理内存和虚拟内存的占用,两者相去甚远.此外,可以用 Hook API 技术来证明每秒调用 SetProcessWorkingSetSize 的行为.

应该怎么做

这篇文章只想让用户了解软件占用资源的实际.而程序员应该把下功夫,真正从代码中减少内存的消耗,而不是一味忽悠用户.调用 SetProcessWorkingSetSize 会带来某些好处,但是何时调用、如何调用应该符合两个要求:
1,在程序暂时不被使用的时候(例如最小化);
2,物理内存和虚拟内存应处于一个合适的比例(而不是 600 KB 比 20 MB 这么荒唐);
3,或者不调用,让 Windows 去处理.
(本人技术有限,对于文中的错误恳请高手给予指正)

[ 本帖最后由 RegKiller 于 2007-12-26 20:49 编辑 ]
金币:
奖励:
热心:
注册时间:
2007-8-12

回复 使用道具 举报

签到天数: 292 天

发表于 2007-12-26 20:46 | 显示全部楼层
学习了:*19*: :*19*: :*19*:
金币:
奖励:
热心:
注册时间:
2004-11-7

回复 使用道具 举报

发表于 2007-12-26 20:47 | 显示全部楼层
咋没去狂欢呢?还在这里值班,辛苦!
金币:
奖励:
热心:
注册时间:
2002-10-17

回复 使用道具 举报

发表于 2007-12-26 20:50 | 显示全部楼层
太专业了,搞不懂的。
金币:
奖励:
热心:
注册时间:
2007-11-13

回复 使用道具 举报

发表于 2007-12-26 20:54 | 显示全部楼层
不懂。
请问深男,我用内存扫把,据说可以释放内存,不知有没有用。
谢谢。
金币:
奖励:
热心:
注册时间:
2007-6-6

回复 使用道具 举报

发表于 2007-12-26 20:59 | 显示全部楼层
试验了所有在wikipedia中提及的所有bt client的windows版本,大概有20几种之多,最后还是老老实实用flashget,这个有80多k,别的基本上都只有1。几k,郁闷啊,我的可是宽带,不能bt,就太浪费了。

不知道bitcomet flashget thunder哪一个最不伤硬盘?
金币:
奖励:
热心:
注册时间:
2007-12-14

回复 使用道具 举报

签到天数: 1 天

发表于 2007-12-26 21:02 | 显示全部楼层
这回不错..可以近离.和深男见面..
金币:
奖励:
热心:
注册时间:
2007-10-10

回复 使用道具 举报

发表于 2007-12-26 21:02 | 显示全部楼层
原帖由 modi911 于 2007-12-26 20:54 发表
不懂。
请问深男,我用内存扫把,据说可以释放内存,不知有没有用。
谢谢。

内存扫把是没用滴,用个RamDisk还差不多,当然了你的物理内存在足够大才行。呵呵。。。
金币:
奖励:
热心:
注册时间:
2002-10-17

回复 使用道具 举报

发表于 2007-12-26 21:06 | 显示全部楼层
这个win API函数我还没用过,今天学习了!
金币:
奖励:
热心:
注册时间:
2006-11-4

回复 使用道具 举报

发表于 2007-12-26 21:39 | 显示全部楼层
学习,,,,,,,,,,,,,,,,,
金币:
奖励:
热心:
注册时间:
2007-4-14

回复 使用道具 举报

发表于 2007-12-26 21:40 | 显示全部楼层
太专业了,搞不懂的。
金币:
奖励:
热心:
注册时间:
2006-12-12

回复 使用道具 举报

发表于 2007-12-26 21:59 | 显示全部楼层
:) :)
金币:
奖励:
热心:
注册时间:
2007-12-1

回复 使用道具 举报

发表于 2007-12-26 22:08 | 显示全部楼层
ding

>
金币:
奖励:
热心:
注册时间:
2001-7-5

回复 使用道具 举报

发表于 2007-12-26 22:43 | 显示全部楼层
太专业了,搞不懂的
金币:
奖励:
热心:
注册时间:
2002-10-23

回复 使用道具 举报

发表于 2007-12-26 22:49 | 显示全部楼层
学习一下。谢谢
金币:
奖励:
热心:
注册时间:
2007-3-26

回复 使用道具 举报

发表于 2007-12-26 22:56 | 显示全部楼层
佩服大盗。学到东西了!绝对的好文章!
金币:
奖励:
热心:
注册时间:
2007-4-26

回复 使用道具 举报

发表于 2007-12-26 23:01 | 显示全部楼层
:*19*: :*19*: :*19*:
金币:
奖励:
热心:
注册时间:
2007-4-1

回复 使用道具 举报

发表于 2007-12-26 23:19 | 显示全部楼层
文章写得非常好!明白了,谢谢深男大盗转摘文章!要是以后能在这儿经常读到这类文章该多好啊。:*19*:
金币:
奖励:
热心:
注册时间:
2006-12-1

回复 使用道具 举报

发表于 2007-12-27 01:50 | 显示全部楼层
:*19*:

学习和炒股两不误!
好!
金币:
奖励:
热心:
注册时间:
2007-5-14

回复 使用道具 举报

发表于 2007-12-27 08:15 | 显示全部楼层
太专业了,搞不懂的。
金币:
奖励:
热心:
注册时间:
2006-10-18

回复 使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

本站声明:MACD仅提供交流平台,请交流人员遵守法律法规。
值班电话:18209240771   微信:35550268

举报|意见反馈|手机版|MACD俱乐部

GMT+8, 2025-4-30 23:25 , Processed in 0.037379 second(s), 12 queries , MemCached On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表