电子商务|GlobalLock的前世今生3: 进入Win32的世界

电子商务|GlobalLock的前世今生3: 进入Win32的世界

至此 , 你应该明白16位Windows的内存管理器是如何处理全局堆了 。 是时候来进入32位的Windows的世界了 。
到了32位之后 , GlobalAlloc会继续和之前一样模拟所有内存移动规则 , 但是GlobalAlloc的返回值不再是一个选择子(Selector) , 因为在Win32中 , 处理器是运行在平坦地址模式(Flat Mode) 。
这意味着 , 之前缓存选择子并在底层重新分配内存的技法不再有效 。
内存的移动性语义被完整地保留下来 。 内存块依然会有一个属性叫做锁定计数 , 即使它并没有什么意义 , 因为Win32系统从来都不会对内存进行压缩(请回忆一下 , 锁定计数是用来防止内存在压缩期间进行移动的一个属性) 。
如果不是为了照顾GlobalFlags这个函数 , 可移动内存和锁定计数可以被完全地从系统中移除 。 GlobalFlags会返回一些奇怪的位信息模式 , 但现在这些信息都和内存不相关了 , 唯有锁定计数这一项信息 。 所以 , 锁定计数依然保留 , 以防止有一些应用程序会使用到它 , 或者一个程序会预期GlbalReAlloc会在一个已锁定的内存块上执行失败 。
除此之外 , 一块可移动内存除了上述的开销之外 , 并不能给你带来什么其他的东西 。
另外一个函数 , LocalAlloc也是一样 , 它依然会带有内存移动性的操作开销 , 但是因为在Win16上 , 本地内存不会在DLL之间传递 , 所以本地堆相关的函数不会像全局堆那样会带有16位兼容性开销的问题 。
在Win32上 , 基于上面的原因 , 推荐使用LocalAlloc 。
(当然了 , 很多函数在内存分配时 , 需要指定一个特殊的类型 , 这个时候 , 你就不会有太多选择 。 例如 , 剪贴板就需要一个可移动的全局句柄 , 另外 , COM需要使用一个任务分配器)
接下来 , 我们将会关注内存的锁定是如何实现的(虽然它也不会做什么有实际意义的操作) 。
总结拓扑梅尔智慧办公平台(Topomel Box):还是Win32对我们好 , API丰富 , 兼容性也好 , 文档又全面 。
Win11:还没好够…(DOG)
最后Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一 , 里面有很多关于Windows的小知识 , 对于广大Windows平台开发者来说 , 确实十分有帮助 。
本文来自:《A history of GlobalLock part 3: Transitioning to Win32》
【电子商务|GlobalLock的前世今生3: 进入Win32的世界】