csatblogspotdotcom

Saturday, August 14, 2010

win7的UAC造成的卡机问题的解决

前两个月解决的一个win7相关的问题:

在重装了win7后突然发现一种奇怪的现象:间歇性卡机,卡的时候啥也干不了,按道理我这种笔记本配置(Athlon X2 QL-64的CPU,2G DDR2 667MHz的内存,西数5400转/分的250G硬盘)运行个win7完全没问题,之前用的也好好的。于是我尽量减少一些不必要的程序的启动,而且也关掉了一些搜索索引相关的,等等吧,一些服务,但仍然间歇性卡机。网上搜了一大堆,找不到头绪。

转机出现在我注意到了一个现象:卡机的时候硬盘灯一直亮!于是使用win7自带的资源监视器,看看硬盘的相关情况。等到卡机的时候终于发现是那个foxmail的问题,关掉foxmail后就好了。打开foxmail继续观察,发现有个VirtualStore文件夹,foxmail一直朝里面写东西,google之,没有相关中文信息,没办法,只有搜索英文的(win7刚出不久,中文信息很少,尤其对于这种比较邪门的问题)。最后发现是win7的UAC机制的原因。UAC对于没有授权,但又想朝相关文件夹写东西的程序,使用了一种类似沙盒的机制,把这些写入的东西全写到一个指定的系统能控制到的安全的地方:VirtualStore文件夹,也就是C:\Users\XXX\AppData\Local\VirtualStore\。结果是foxmail以为自己写入了C:\Program Files (x86)\Foxmail\,实际上是写入了C:\Users\XXX\AppData\Local\VirtualStore\Program Files (x86)\Foxmail\。而如果需要修改的文件很大,例如foxmail的in.BOX之类的文件,在拷贝的时候(先把文件拷贝到VirtualStore再对VirtualStore中的文件进行修改),就会很耗时,而且很卡(这里有一点我想不太明白,为什么微软不把这个设计的更人性化一些呢,不要让它写的时候就霸占了所有资源,不让别人动了,毕竟我还是双核的本本啊,磁盘你也不要一直霸着写啊。这应该算是这个机制的一个bug吧)。

继续在网上读相关文章,找到了相应的解决方法:赋予这个应用程序相应的写权限。具体的操作可以是重新安装这个程序(我承认这个foxmail是我从原系统拷贝过来,把它当成了绿色软件来用的);也可以修改foxmail文件夹的属性,让当前用户可以对其进行写操作。我是直接修改文件夹属性,OK。之后发现VirtualStore里还有迅雷,刚打开迅雷的时候确实会卡一小会,觉得这个不影响大局,就不管了。

在解决这个问题的过程中我也学会了使用一个有用的工具procmon.exe,和procexp.exe类似,都是微软出的系统性能监视软件,不同的是前者针对于程序和性能的具体行为,是微观上的,而后者针对于程序和进程的表现,是宏观上的(个人理解哦)。

后来有个同事有同样的问题,说卡时强行关机后再开机就没问题了,但第二天问题仍会出现。难道强行关机后它就记得已经拷贝过去了?相关标志位已经被设为了正在拷贝?所以就不会拷贝了?应用程序重新启动后标志位就重新被清零,重新标识为未拷贝?(帮他设置好后过了好一段,前天问这个同事好了没,他说没死机了,顿了会又补了句说后来死了两次,之后就没了。。。真是搞笑!以后这种人要是不请我搞,我就不理会他的问题了)

之前玩斗地主时,发现每次都提示是否允许斗地主程序对系统的修改,我以为这家伙要下载更新,每次都拒绝了,今天重新看VirtualStore文件夹时发现其大小很大,进去一查原来是斗地主的问题。这时一切都清楚了:对于一个有写权限的程序来说,不存在问题;而对于一个没有写权限但又想进行写操作的程序来说,如果只是创建一个新的文件,没问题,只是写的地方不同,一个是原位置,另一个是在VirtualStore文件夹里面,对用户来说没有感知上的区别;但是如果是修改原位置的文件则需要先拷贝到VirtualStore中,再修改VirtualStore中的文件。原文件小的话,还是没问题,拷贝一个小文件有多大问题呢?毕竟现在能运行win7的机子的配置都蛮不错的;而如果需要修改也就是需要拷贝的文件很大的话,例如foxmail里面的收件箱之类的文件,问题就来了,写操作会把整台机子给霸了(微软是这样设计的),这时看到的现象就是:硬盘灯一直亮啊闪啊,鼠标键盘完全没反应,Num Lock键也没反应,让人以为是死了,其实是卡住了,耐心的等等还是等的来的,只不过等来之后,过一会还会出现这个问题:每次要修改就拷贝--它不记得之前已经拷贝过了(这点我真的不明白,为什么它不记得之前拷贝过,每次都要重新拷贝呢,我感觉这个问题很重要,但真实原因不得而知,可能是怕在拷贝并对VirtualStore里的文件修改之后,其它有权限的程序对原属文件夹里的文件进行操作,这样它需要更新吧,于是就每次修改都会拷贝一次以保证VirtualStore中数据的正确性和完整性,如果不是每次都拷贝,这样就存在两个文件不一致的可能。但这可以通过设置一些变量并比较来解决,而不需要用每次拷贝这种蛮办法啊,也许当时的设计人员每想到拷贝会造成什么问题吧。同时原文件也没法删,如果删了只留VirtualStore里的那个也不存在反复拷贝的问题了)。

刚才也看到VirtualStore里有个a.out文件,属于我前两天装的MinGW和MSYS的,于是我想到了前两天在MSYS这个模拟器里touch了一个文件,但到相应目录啥也没找到,于是创建了一个b文件,果然在VirtualStore相应文件夹中找到了“b”,同时还有一个“.bash_history”,把这个文件移到应属的文件夹后,VirtualStore里就没出现它了。从这里面可以看出,修改和创建文件是两个不同的操作!因为没有权限创建文件,所以被重定向到了VirtualStore;但可以修改和删除,于是把文件移动到原属文件夹后,就没有在VirtualStore产生新的文件了。后来我用这个实验证实了修改权限的存在:echo a > b,发现VirtualStore里的b里面的内容为a;把b移动到原属文件夹,echo bbb > b,发现原属文件夹里的文件的内容为bbb,而VirtualStore里没有新增b文件;而不管是VirtualStore里的文件还是原属文件夹里的文件,rm都可以删除,证实了删除权限的存在。(注意:这里的echo是个脚本,touch和rm是exe文件,echo和touch.exe以及rm.exe三个文件的权限一样!MSYS是个模拟器,把windows的接口通过windows上的这几个小程序转换成linux命令。)(这里还有一点,在VirtualStore中创建了文件后,以后每次都直接往里写了,没有一个拷贝的过程,很好。)

看来以后在win7里不能随便用绿色软件了,要把软件安装上去。下次运行斗地主提示我允许修改不的时候,也要允许了,免得往VirtualStore里写。





后记:win7间歇性死机

2010-08-22 04:01
在解决win7间歇性死机的过程中,系统自带的资源监视器起了很大作用,用它可以直接观测到到底是哪个程序狂读写磁盘,哪个程序占用了CPU资源,等等。
这个工具可以用perfmon直接调出(我觉得翻译成性能监视器更好,看名字显然是performance monitor,可能是性能监视器的名字已经被占用了吧)。

Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home