请问高手中的高手来指点一下,有以下两个问题困惑几天.
环境: VS2005 smart + PPC 2003 SE模拟器下开发运行.
一) 目前自己来负责做内存管理模块, 局部策略实现最终需要和系统打交道, 比如在申请虚拟地址空间时,
用到了virtualalloc函数,不解的时,调用virtualalloc时候,参看题为,
"Windows CE 进程、线程和内存管理(三)"一文, 0x4200 0000到0x7FFF FFFF,
我也不知道,怎么应用, 查看MSDN,可以第一参数可以默认为0, 不指定地址范围.
如果,
WORD aMaxSizes = 22*1024*1024;
void *Addr = VirtualAlloc((LPVOID)0x42000000, aMaxSizes, MEM_RESERVE, PAGE_READWRITE);
Addr = 0x00000000?
如果,
m_pBaseAddr = VirtualAlloc((LPVOID)0, aMaxSizes, MEM_RESERVE, PAGE_READWRITE);
Addr = 0x00150000, 不是落在0x4200 0000到0x7FFF FFFF之间的?
此时取得DWORD nErr = GetLastError();
error code 是126 : 找不到指定的模块
请问,上面的用法有什么问题?
如何真正保证申请的虚拟地址空间落在0x4200 0000到0x7FFF FFFF这个大的范围内.
二) 问题是如何查看和监视模拟器PPC 下的内存状况?
什么工具和方法?
谢谢高手中的高手关注一下. 不知道查什么好, MSDN也是通而无用.
第一问题没看明白。
第二个问题不知道你需要查看哪些状况?remote工具可以查看内存的一些状况,但不知道是不是你需要的。
谢谢楼上的回复.
关于第一个问题,就是VirtualAlloc的用法,看了一个周,云里雾里,说到底是不知道怎么用?
第2个问题,是想找个WinCE内存监视工具,可以查看当前程序内存的大小,以及当前可用内存的大小和内存使用率等,
VS 2005怎么没Remote system information 这个了.
没有人说VirtualAlloc分配出来的空间就是落在0x4200 0000到0x7FFF FFFF之间的!!
从0x00000000 到 0x41FFFFFF 是所有应用程序共同使用的, 共分33个槽, 每个槽占用32M. 只有当某些进程32M地址空间不能够满足的时候,才调用0x4200 0000到0x7FFF FFFF
所以 m_pBaseAddr = VirtualAlloc((LPVOID)0, aMaxSizes, MEM_RESERVE, PAGE_READWRITE); //应该你的进程没有用完32M吧
Addr = 0x00150000, 不是落在0x4200 0000到0x7FFF FFFF之间的? //所以这个问题也很清楚了.
void *Addr = VirtualAlloc((LPVOID)0x42000000, aMaxSizes, MEM_RESERVE, PAGE_READWRITE); //至于这个等于Null的话,你可以查看Getlasterror 获得一些信息. 我这里没法试
还有一种说法可以参考:
在CE5.0之前,使用VirtualAlloc获得的虚拟地址空间分为两种情形:
(1)大小在2MB以下时,位于调用进程的虚拟空间中;
(2)大小大于2MB时,位于用户态的共享地址空间内(0x42000000-0x7E000000 )
呵呵,vs2005里没有,你还可以回去用evc的啊
virtual没用过了。
自己研究一下,还需要大家来关注,辛苦了...
一)对问题一,
VCKBASE 的文章http://www.vckbase.com/document/viewdoc/?id=1156
和 MS mvp写的Windows CE .NET 高级内存管理 一文,
之后有所了解关于CE虚拟内存布局和应用程序虚拟内存的布局情况,
不过请问大家有谁知道,为什么
当请求的一块保留区
VOID*P2 = VirtualAlloc((void *)0x46000000, 5*1024*1024, MEM_RESERVE, PAGE_READWRITE);
DWORD nErrcode = GetLastError();
nErrcode =8 , 存储空间不足,无法处理此命令。 到底是怎么回事情?
我使用 MEMORYSTATUS MemStatus;
GlobalMemoryStatus(&MemStatus);
查看可用的物理内存和虚拟内存都超过5M?
二)对问题二,用GlobalMemoryStatus和GetSystemInfo函数。
建议你去看看我的blog
http://blog.eeworld.net/nbcool
你说的那篇 MSDN上的 Windows CE.NET 高级内存管理,并不完整,只能做为补充资料。
1.如果虚拟地址不连续,怎么给你分配5M?
2.研究内存问题,工具和方法很多,不必局限在某个API。
关于virtualalloc方面的问题, 还有很多实际的疑惑.
1. 我们用的VS2005 PPC 2003 是模拟器的环境相当于WINCE什么版本?
2. CE4.0和5.0虚拟内存布局方面有什么同异?
3. virtualalloc分配的结果总是与预料不同?
4. 模拟器下内存大小怎么样调节?
载舟之水,谢谢你了,我先看看, 有时间希望能交流一下.
做开发做了四五年对靠底层的东西还是缺乏实际的经验,呵呵.
1. PPC2003有第一版和第二版PPC2003 SE,现在一般用的是第二版本,内核是WinCE.net 4.2
2. CE4.0内存管理和 CE.net 4.2 CE5.0 是有些小差异的,后两者是相同的。
3. 正确的使用方法能得到正确的结果,如果每次都和预料不一样,那不成了彩票了?
4. PPC 2003 模拟器能调节应用程序空间和对象存储空间的分配,PPC 5.0之后,已经统一了这两块空间,不再提供调节。
载舟之水, 很感谢你的再一次关注,
我有点两点疑问:
一)
PPC2003 SE VS2005建个工程,
VOID* addr = VirtualAlloc((void*)0x42000000, 10, MEM_RESERVE, PAGE_READWRITE);
DWORD nErrcode = GetLastError();
发现addr是0, 是关于nErrcode =8, 存储空间不足,无法处理此命令? 只申请10个BYTE的虚拟空间.
存在什么问题呢?
补充说一下我对VirtualAlloc的用法理解, 理解错误或片面,还望多多指教
如果第一个参数是0, 那么系统来确定基地址, 但在0x00010000--0X2000000 32M的虚拟空间内,当然系统本地heap, stack, 静态数据段和代码等预留的除外;
如果第一个参数非0, 也就是当需求增大扩充虚拟空间. 这个时候需要指定的空间, 0x42000000--0x7FFFFFFF之间,
对第二个参数, 建议是PAGE_SIZE自动对齐,因为会导致重复覆盖的情况, http://www.cnblogs.com/walzer/archive/2007/01/22/626562.html有文说明验证过.
二) PPC 2003 模拟器能调节应用程序空间和对象存储空间的分配,不知何处?
留下这两个问题.
VOID*addr = VirtualAlloc((void *)0x46000000, 64*1024, MEM_RESERVE, PAGE_READWRITE);
DWORD nErrcode2 = GetLastError();
// addr =0, nErrcode2 =8 存储空间不足,无法处理此命令
VOID*P = VirtualAlloc((LPVOID*)0, 5*1024*1024, MEM_RESERVE, PAGE_READWRITE);
VOID*addr = VirtualAlloc((LPVOID*)P, 1*1024*1024, MEM_RESERVE, PAGE_READWRITE);
DWORD nErrcode2 = GetLastError();
// addr =0, nErrcode2 =87 参数不正确
我建议你还是反复仔细地研读正确的资料,比如MSDN,以及在我的blog中的译文,另外,多参考 Microsoft的 sample code。
你的代码中问题很多,我无法一一指出,只能提醒一下,
1.你在0x46000000 分配时,并没有先去查询是否有空间可供分配,如果只有63*1024,那自然会报告存储空间不足。
2.参数确实错了。
VOID*addr = VirtualAlloc((LPVOID*)P, 1*1024*1024, MEM_RESERVE, PAGE_READWRITE);
//在付林林编辑的一本PB书里,说到到传递的地址不为0时,返回值永远都是不正确的. 但是书里没有说明原因, 也许这就是wince的特点?!
//可是msdn却没有说明这一点.
这些问题应该不是存不存在这么大空间的问题.
摘自原文:
在实践中发现给参数1传递非0值均不成功,即使传递0给参数1让内核自动查找空闲地址空间,得到的返回值赋给参数1再次调用此函数(之前已经释放第一次申请的地址空间)也不成功. 所以在调用 VirtualAlloc函数时尽量传递0给参数1.如果申请的虚拟空间超过一定范围,那么内核将在0x42000000 到 0x7FFFFFFF 之间分配地址空间.
//另外,如果楼主仅仅是研究这一现象也罢了,如果实际应用中 还是建议使用内存映射文件技术 来解决大物理空间问题.
是的,第二参数的确错了,后来我发现,针对非0的情况,用法是有点武断,呵呵,谢谢各位,载舟之水和KevinCEC ,谢谢你们你们的回复,载舟之水的翻译MS MVP -Douglas Boling的文章不错, 技术坚定和视野开阔,绝对是中华武林高手.
补充一下,参数错是因为,
VOID*P = VirtualAlloc((LPVOID)0, 5*1024*1024, MEM_RESERVE, PAGE_READWRITE);
VOID*Q = VirtualAlloc((int*)P+5*1024*1024, 1*1024*1024, MEM_RESERVE, PAGE_READWRITE);
这个时候Q可获取合理的虚拟地址了. 准备就给大家分了, 我嫌给分太少, 人生道路朋友才珍贵. 呵呵!
另外说一下,付林林并不是内存方面的专家,他对内存问题也是一知半解,很久以前我就指出过他文章的多处问题。我前面说的看正确的资料,一定是要以MSDN上的文章为准的,尽管MSDN也有不少错误,但是还是比较可信的。MS MVP Douglas Boling被微软誉为对WINCE理解最完美的人之一,所以他的文章也具有参考价值。
既然今天来eeworld(有几年没来了),碰到高手就说上几句。我不是什么高手。相对来说,技术的深处还研究不够。
目前在移植和开发某平台引擎,里面有块就要用到内存管理的部分。04年过sa,每天仍坚持学习两三个小时,主要研究
设计模式和架构,更早的时候也是学技术COM,研究ATL源码,后来从分布式架构到目前的嵌入式领域通信架构、应用,
直到OS 内核的架构,我也就不再探究了,其实倒有些兴趣。我一直看书,都在致力于将花拳绣腿的模型经过验证变成可执行的模型,却可能又偏偏有些忽视了实现本身的一些东西,如算法和计算机知识等问题。不过,我更重要是在修养自己的品格。讲一个我们中国人可能容易忽视的品格吧, 敢于质疑和创新, 是科学发展的最核心的力量. 见笑的地方,来eeworld,工作紧迫,思维和测试代码未经整理。呵呵,幸会,中国有载舟之水,所言有理,非常谢谢你的回复!